NOIP普及组|2009T1多项式输出
NOIP2009年普及组第一题:多项式输出
题目描述
一元 nnn 次多项式可用如下的表达式表示:
f(x)=anxn+an−1xn−1+⋯+a1x+a0,an≠0f(x)=a_nx^n+a_{n-1}x^{n-1}+\cdots +a_1x+a_0,a_n\ne 0f(x)=anxn+an−1xn−1+⋯+a1x+a0,an=0
其中,aixia_ix^iaixi 称为 iii 次项,aia_iai 称为 iii 次项的系数。给出一个一元多项式各项的次数和系数,请按照如下规定的格式要求输出该多项式:
- 多项式中自变量为 xxx,从左到右按照次数递减顺序给出多项式。
- 多项式中只包含系数不为 000 的项。
- 如果多项式 nnn 次项系数为正,则多项式开头不出
+
号,如果多项式 nnn 次项系数为负,则多项式以-
号开头。- 对于不是最高次的项,以
+
号或者-
号连接此项与前一项,分别表示此项系数为正或者系数为负。紧跟一个正整数,表示此项系数的绝对值(如果一个高于 000 次的项,其系数的绝对值为 111,则无需输出 111)。如果 xxx 的指数大于 111,则接下来紧跟的指数部分的形式为“xbx^bxb”,其中 bbb 为 xxx 的指数;如果 xxx 的指数为 111,则接下来紧跟的指数部分形式为 xxx;如果 xxx 的指数为 000,则仅需输出系数即可。- 多项式中,多项式的开头、结尾不含多余的空格。
输入格式
输入共有 222 行
第一行 111 个整数,nnn,表示一元多项式的次数。
第二行有 n+1n+1n+1 个整数,其中第 iii 个整数表示第 n−i+1n-i+1n−i+1 次项的系数,每两个整数之间用空格隔开。
输出格式
输出共 111 行,按题目所述格式输出多项式。
输入输出样例 #1
输入 #1
5
100 -1 1 -3 0 10
输出 #1
100x5-x4+x3-3x2+10
输入输出样例 #2
输入 #2
3
-50 0 0 1
输出 #2
-50x^3+1
说明/提示
对于100%数据,0≤n≤1000 \le n \le 1000≤n≤100,$-100 \le 系数系数系数 \le 100$
大家好,我是莫小特。
这篇文章我将和大家一起来解决NOIP2009年普及组第一题:多项式输出。
题目信息
洛谷链接:P1067 多项式输出
一、完成输入
根据输入格式的描述,输入的第一行为整数 n,表示一元多项式的次数,数据范围小于等于 100,所以使用 int 类型。
int n;
cin>>n;
接下来有 n+1 个数,分别代表从第 n 次到第 0 次的系数,考虑到需要按格式输出,所以用数组 a 来存储每一项的系数,数组元素个数为 200。
int a[200]={0};
使用 for 循环输入这 n+1 个数,下标从 0 开始。
for(int i=0;i<=n;i++)
{cin>>a[i];
}
输入完成后,我们接下来分析题意来解决问题。
二、分析题意
根据题目描述,我们需要题目中给定的格式来输出对应的多项式。
简要分析题目中的格式描述。
(1)首项不能有 + 号
(2)每一项要根据次数分类
(3)系数为 ±1 时要省略数字
(4)系数为 0 的要跳过
(5)所有的符号正反都要手动控制
先实现第一项,使用 for 循环遍历输入的数组a,并用新变量存储每一个系数的值,如果系数为 0,使用 continue 跳过。
for(int i=0;i<=n;i++)//遍历输入的数组
{int k=a[i];//将k赋值为a[i]的值,方便使用if(k==0) continue;//如果系数为0,则跳过
}
并且也需要记录当前项的次数,使用 power 变量来记录。
int power=n-i;//记录当前项的次数 如果 i=0 次数就是 n
要在程序的判断之前,所以将代码调整成这样。
for(int i=0;i<=n;i++)//遍历输入的数组
{int k=a[i];//将k赋值为a[i]的值,方便使用int power=n-i;//记录当前项的次数 如果 i=0 次数就是 nif(k==0) continue;//如果系数为0,则跳过
}
接下来处理每一项的符号,因为第一项不能有 +,如果是负数,则要出现 - 号。
这一步,可以使用一个 bool 变量来判断第一项,用于控制首项 +,后续的正数项必须加 + 号,注意,这个加在循环之前。
bool first=true;
如果是首项,也就是 first==true
,系数如果是负数,正数不输出符号。
如果不是首项,系数如果为负数,输出负号 -
,如果系数为正数,输出正号 +
。
if(first==true)
{if(k<0) cout<<"-";//首项小于0输出负号
}
else//不是首项
{if(k<0) cout<<"-";//输出负号else cout<<"+";//输出正号
}
整合代码。
bool first=true;
for(int i=0;i<=n;i++)//遍历输入的数组
{int k=a[i];//将k赋值为a[i]的值,方便使用int power=n-i;//记录当前项的次数 如果 i=0 次数就是 nif(k==0) continue;//如果系数为0,则跳过 if(first==true){if(k<0) cout<<"-";//首项小于0输出负号}else//不是首项{if(k<0) cout<<"-";//输出负号else cout<<"+";//输出正号}
}
符号输出完成后,我们要输出系数,如果次数为零则直接输出绝对值,不需要输出后续的 x^
,即常数项 power == 0
,直接输出绝对值,无需写 x,也无需判断系数是否为 1。
if(power==0)
{cout<<abs(a[i]);
}
其余情况则需要输出对应的值和 x^
,由于之前已经输出符号,所以只需要输出对应值的绝对值即可,使用 abs()
函数。
如果值为 1,不需要输出这个值。
如果系数绝对值不是 1,就输出它,
如果是 1,就省略(只显示 x 或 -x)
若 power == 1
,只输出 x,若 power > 1,输出 x^k
。
else
{if(abs(a[i])!=1) cout<<abs(a[i]);cout<<"x";//随后输出xif(power>1) cout<<"^"<<power;
}
最后更新 first 标记。
first=false;
整合代码:
bool first=true;
for(int i=0;i<=n;i++)//遍历输入的数组
{int k=a[i];//将k赋值为a[i]的值,方便使用int power=n-i;//记录当前项的次数 如果 i=0 次数就是 nif(k==0) continue;//如果系数为0,则跳过 if(first==true){if(k<0) cout<<"-";//首项小于0输出负号}else//不是首项{if(k<0) cout<<"-";//输出负号else cout<<"+";//输出正号}if(power==0){cout<<a[i];}else{if(abs(a[i])!=1) cout<<abs(a[i]);cout<<"x";//随后输出xif(power>1) cout<<"^"<<power;}first=false;
}
按样例输入来验证数据。
符合样例输出的要求,可以到网站提交测评!
三、验证数据
提交到洛谷网站进行测评,通过!
四、完整代码
完整代码如下:
#include <iostream>
using namespace std;
int main()
{int n;cin>>n;int a[200]={0};for(int i=0;i<=n;i++){cin>>a[i];}bool first=true;for(int i=0;i<=n;i++)//遍历输入的数组{int k=a[i];//将k赋值为a[i]的值,方便使用int power=n-i;//记录当前项的次数 如果 i=0 次数就是 nif(k==0) continue;//如果系数为0,则跳过 if(first==true){if(k<0) cout<<"-";//首项小于0输出负号}else//不是首项{if(k<0) cout<<"-";//输出负号else cout<<"+";//输出正号}if(power==0){cout<<abs(a[i]);}else{if(abs(a[i])!=1) cout<<abs(a[i]);cout<<"x";//随后输出xif(power>1) cout<<"^"<<power;}first=false;}return 0;
}
五、技巧总结
本题考察了字符串格式化输出与条件逻辑控制的综合能力,是NOIP普及组中非常经典的模拟实现类题目。题目虽不涉及算法核心,但细节要求极高,容易出错。
本题的核心考点有以下几点:
1、条件判断的分支控制
- 首项不能输出 + 符号;
- 非首项根据系数符号输出 + 或 -;
- 需使用
bool first
来判断是否为首项,避免冗余判断。
2、系数为 ±1±1±1 的特殊处理
- 若次数 > 0 且系数为 ±1,要省略 1;
- 若次数为 0,即常数项,必须保留数字 1;
- 使用
abs()
函数配合逻辑判断处理即可。
3、多项式不同次数的格式变化
x^k
:指数 > 1;x
:指数为 1;- 常数项:指数为 0,仅输出数字;
指数值不同的格式,是此类题目的高频陷阱,建议使用分支清晰地分类处理
如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、关注我哦!
如果有更好的方法也可以在评论区评论哦,我都会看哒~
我们下集见~