P1067 [NOIP2009 普及组] 多项式输出

题目描述

一元 n n n 次多项式可用如下的表达式表示:

f ( x ) = a n x n + a n − 1 x n − 1 + ⋯ + a 1 x + a 0 , a n ≠ 0 f(x)=a_nx^n+a_{n-1}x^{n-1}+\cdots +a_1x+a_0,a_n\ne 0 f(x)=anxn+an1xn1++a1x+a0,an=0

其中, a i x i a_ix^i aixi 称为 i i i 次项, a i a_i ai 称为 i i i 次项的系数。给出一个一元多项式各项的次数和系数,请按照如下规定的格式要求输出该多项式:

  1. 多项式中自变量为 x x x,从左到右按照次数递减顺序给出多项式。

  2. 多项式中只包含系数不为 0 0 0 的项。

  3. 如果多项式 n n n 次项系数为正,则多项式开头不出 + 号,如果多项式 n n n 次项系数为负,则多项式以 - 号开头。

  4. 对于不是最高次的项,以 + 号或者 - 号连接此项与前一项,分别表示此项系数为正或者系数为负。紧跟一个正整数,表示此项系数的绝对值(如果一个高于 0 0 0 次的项,其系数的绝对值为 1 1 1,则无需输出 1 1 1)。如果 x x x 的指数大于 1 1 1,则接下来紧跟的指数部分的形式为“ x b x^b xb”,其中 b b b x x x 的指数;如果 x x x 的指数为 1 1 1,则接下来紧跟的指数部分形式为 x x x;如果 x x x 的指数为 0 0 0,则仅需输出系数即可。

  5. 多项式中,多项式的开头、结尾不含多余的空格。

输入格式

输入共有 2 2 2

第一行 1 1 1 个整数, n n n,表示一元多项式的次数。

第二行有 n + 1 n+1 n+1 个整数,其中第 i i i 个整数表示第 n − i + 1 n-i+1 ni+1 次项的系数,每两个整数之间用空格隔开。

输出格式

输出共 1 1 1 行,按题目所述格式输出多项式。

样例 #1

样例输入 #1

5 
100 -1 1 -3 0 10

样例输出 #1

100x^5-x^4+x^3-3x^2+10

样例 #2

样例输入 #2

3 
-50 0 0 1

样例输出 #2

-50x^3+1

提示

NOIP 2009 普及组 第一题

对于100%数据, 0 ≤ n ≤ 100 0 \le n \le 100 0n100,$-100 \le 系数 系数 系数 \le 100$


upd 2022.8.1 \text{upd 2022.8.1} upd 2022.8.1:新增加一组 Hack 数据。

1.题目分析

输入一个整数代表多项式的最高项指数,接下来依次输入每一项包括常数项的系数。
按照题目要求输出多项式形式即可。

值得一提的是,有很多细节需要考虑:

  • 需要判断系数是否为零
  • 判断系数项符号的问题,首位输出为正数是需要省略前置的+号
  • 判断系数项为正负1时,需要对该系数的1进行省略
  • 判断常数项系数时,需要省略x相关部分
  • 判断x的一次项时,幂指数需要省略1

2.题目思路

输入最高次项的指数,循环输入系数,系数含零直接跳过本轮循环,
判断系数项符号的输出情况,分为两种情况:
一种是负数和首项,一种是正数。
因为非首项的正数需要加前置加号。
这里使用到了string中的substring函数:有用于切割字符串,传参为开始索引,结束索引。

然后分别对两种情况进行嵌套判断:
第一,判断是否为常数项。
第二,对非常数项进行判断,绝对值是否为1以及当前项是否为x的一次项。

值得一提的是,首项可以为正1,也可以为-1,所以在第一种情况下,还需要对首项进行正1的判断。
边判断边打印即可。

3.代码实现

#include 

using namespace std;

int main() {
    int n;
    //输入最高次项的指数
    cin >> n;
    string str;
    for (int i = 0; i < n + 1; ++i) {
        //输入系数
        cin >> str;
        //系数含零直接跳过
        if (str == "0") {
            continue;
        }
        //判断系数项符号的输出情况
        if (str.substr(0, 1) == "-" || i == 0) {
            //负数或者首位 直接输出
            if (i == n) {
                //常数项省略x
                cout << str;
            } else {
                //非常数项
                if (str == "-1") {
                    //非常数项系数为-1的处理
                    if (i == n - 1) {
                        //且当前为x的一次项时
                        cout << "-" << "x";
                    } else {
                        cout << "-" << "x^" << n - i;
                    }
                } else if (str == "1") {
                    //当首位为1时,也要省略1,且不打印正号
                    if (i == n - 1) {
                        //且当前为x的一次项时
                        cout << "x";
                    } else {
                        cout << "x^" << n - i;
                    }
                } else {
                    if (i == n - 1) {
                        //且当前为x的一次项时
                        cout << str << "x";
                    } else {
                        cout << str << "x^" << n - i;
                    }
                }
            }
        } else {
            //正数:开头加+
            if (i == n) {
                //常数项省略x
                cout << "+" << str;
            } else {
                //非常数项
                if (str == "1") {
                    //非常数项中的1的处理
                    if (i == n - 1) {
                        //且当前为x的一次项时
                        cout << "+" << "x";
                    } else {
                        cout << "+" << "x^" << n - i;
                    }
                } else {
                    if (i == n - 1) {
                        //且当前为x的一次项时
                        cout << "+" << str << "x";
                    } else {
                        cout << "+" << str << "x^" << n - i;
                    }
                }
            }
        }
    }
    return 0;
}

你可能感兴趣的:(刷题go,go,go,算法,c++)