跳转至

BISHI18 多项式输出

简单通过率 29.58%python3样例通过牛客 AC

牛客原题  源码

讲解章节多项式

一句话

按给定规则把系数序列格式化成多项式字符串。

解题思路

这题考什么

没有算法,全部难度在「把一段自然语言规则不重不漏地翻译成分支」。 这类题的正确写法是把每一项拆成「符号 + 系数 + 变量部分」三段, 每段各自定规则,最后拼起来,而不是靠一堆 if 去覆盖各种组合。

符号:第一个被输出的项若为正则不写,其余正项写 '+',负项一律写 '-';
      符号只跟「是不是第一个输出的项」有关,与次数无关。
系数:取绝对值;次数 >= 1 且绝对值为 1 时整个数字省略;常数项永远写出。
变量:次数 0 不写,次数 1 写 "x",次数 >= 2 写 "x^k"。

三段规则互不干扰,各写一行就完事;混在一起判断就会漏掉 「-1 作为常数项」这类组合。多项式的表示与运算见 24-多项式

数据规模与复杂度

n <= 100,最多 101 项,O(n)。输入输出都极小,写法上没有性能压力, 只要保证一次性输出、结尾恰好一个换行即可。

坑在哪

  1. 系数为 0 的项整项省略,包括常数项:不能因为「常数项特殊」就把 0 也印出来;
  2. 次数 >= 1 且 |系数| == 1 时省略这个 1,写成 x 或 x^k; 但常数项的 1 和 -1 必须完整写出,样例 2 结尾的 "+1" 就是这一条;
  3. 次数为 1 写 "x" 而不是 "x^1",次数为 0 只写数字、不带 x;
  4. 「第一个项不带加号」要用「parts 是否为空」来判断,而不是用「idx == 0」。 题目虽然保证 a_n != 0(最高次项一定会被输出,两种写法此时等价), 但用 parts 判空对「前面若干项恰好都是 0」的输入同样正确,写法更稳;
  5. 负号是作为符号写在项前的,系数要先取绝对值再拼, 否则会出现 "+-3x^2" 这种两个符号叠在一起的输出。

样例复核

n = 5、系数 100 -1 1 -3 0 10: 100x^5(首项省 '+')、-x^4(|系数| 为 1 省略数字)、+x^3、-3x^2、 0 次项之上的 x^1 系数为 0 整项省略、常数 10 写作 +10, 拼出 100x^5-x^4+x^3-3x^2+10,与样例一致。

参考实现

solutions/BISHI18.py
import sys

data = sys.stdin.buffer.read().split()
n = int(data[0])
coef = list(map(int, data[1:n + 2]))      # 依次是 a_n, a_{n-1}, ..., a_0

parts = []
for idx, a in enumerate(coef):
    k = n - idx                            # 当前项的次数
    if a == 0:
        continue                           # 系数为 0 的项整项不输出
    # parts 为空说明这是第一个被输出的项,正号省略;否则正项要补 '+'
    sign = "-" if a < 0 else ("+" if parts else "")
    v = abs(a)                             # 正负号已经单独处理,这里只留绝对值
    if k == 0:
        term = str(v)                      # 常数项:即使是 1 也要写出来
    else:
        head = "" if v == 1 else str(v)    # 次数 >= 1 时的系数 1 省略
        term = head + ("x" if k == 1 else "x^" + str(k))
    parts.append(sign + term)

sys.stdout.write("".join(parts) + "\n")
[:octicons-arrow-left-16: BISHI17](BISHI17.md) [BISHI19 :octicons-arrow-right-16:](BISHI19.md)