【代码超详解】HDU 1296 Polynomial Problem 多项式问题(模拟 · 0 ms)

本文详细讲解了HDU 1296 Polynomial Problem的解题思路,包括如何处理输入的多项式表达式,通过模拟计算求解f(x)的值。文章提供了算法分析、代码编写指导,并附带了测试数据和AC代码,适合学习算法和模拟解题。
摘要由CSDN通过智能技术生成

一、题目描述
已知下列表达式

输入包含多组数据,每组数据有两行,第一行是单个整数X,第二行是表达式。要求输出表达式的值 f(x)。保证中间结果在 -1 000 000 000 到 1 000 000 000 之间。输入结束标志 EOF。
样例:
输入

3
1003X^5 +234X^4 -12X^3 -2X^2+987X-1000

(由于CSDN的输入格式的问题,被迫加了些空格防止数字被上标,实际上输入没有空格)
输出

264302

二、算法分析说明与代码编写指导
输入X后要先吞掉紧随其后的回车,否则fgets不能正确读入表达式。
本题的高次项比低次项先输入,因此第一项是最高次的。
设字符串 s 用于保存输入的表达式,c 代表每一项的系数(coefficient),最终答案为 ans ,每项的次数为 Exp(exponent),最高次项的次数为 Expm ,pwr 为从 x 的 1 次方到 Expm 次方的全部值,p 为读取光标,op 为运算符(operator),readx 表示读取每一项时是否已经读到 x 。
对第一项的处理与之后的项稍有不同,所以先读取第一项。系数 c 和次数 Exp 都默认为 1 。
如果最开头是负号,就把运算符 op 改成负号(默认是正),并移动光标到下一个字符。
然后读取系数,保存到 c 中。
接下来,需要判断第一项是常数项还是含 x 的项。如果读到 x ,就移动光标读取 ^ 符号后的次数。如果没有 ^ 符号,就直接移动光标准备读取运算符和下一项。根据 op 来决定第一项的值是正是负。最高次项大于 1 时,就计算 x 从 2 到最高次方的值并保存,这样后续计算的时候就可以直接取相应的结果,无需重复计算。
第一项也有可能是常数,所以需要单独处理一下这种情况。
接下来写一个循环来计算剩下的项的值。这时候光标停在第一项与第二项之间的位置,就是那个运算符上。当然如果只有一项的话,这个位置就是换行符 \n 。这时候直接退出循环并输出即可。如果不是换行,就移动光标准备读取下一项。同样,系数 c 和指数 Exp 都要重设为 1 ,并将 readx 重设为 false ,然后重复第一项的读取方式即可。当然这里直接取前面已经计算过的 x 的 Exp 次幂的结果再乘系数就可以了。注意处理常数项的情形。
读到换行符,循环结束,输出。本例不用将 pwr 数组清零。

三、测试数据

3
X
3
-X
3
2X
3
-2X
3
X^2
3
-X^2
3
2X^2
3
-2X^2
3
-X4+2X3
3
2X5-3X4
3
0
3
1
3
-1
3
X+1
3
-X^2+1
3
2X^3+1

四、AC 代码(0 ms)

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
using namespace std;
#pragma warning(disable:4996)
char s[65536]; int x, c, ans, Exp, Expm, pwr[32], p; char op; bool readx;
int main() {
	for (;;) {
		if (scanf("%d", &x) == EOF)return 0;
		getchar(); fgets(s, 65535, stdin);
		p = 0, c = 1, Exp = 1, Expm = 1, ans = 0, pwr[1] = x, op = '+', readx = false;
		if (s[p] == '-') { op = '-'; ++p; }
		if (isdigit(s[p])) { c = 0; while (isdigit(s[p])) { c = c * 10 + s[p] - 48; ++p; } }
		if (s[p] == 'X') {
			readx = true;
			if (s[p + 1] == '^') {
				p += 2, Expm = 0; while (isdigit(s[p])) { Expm = Expm * 10 + s[p] - 48; ++p; }
				for (int i = 2; i <= Expm; ++i) { pwr[i] = pwr[i - 1] * x; }
			}
			else { ++p; }
			if (op == '+')ans += c * pwr[Expm]; else ans -= c * pwr[Expm];
		}
		if (readx == false) { if (op == '+')ans += c; else ans -= c; }
		for (;;) {
			op = s[p]; if (op == '\n')break;
			++p, c = 1, Exp = 1, readx = false;
			if (isdigit(s[p])) { c = 0; while (isdigit(s[p])) { c = c * 10 + s[p] - 48; ++p; } }
			if (s[p] == 'X') {
				readx = true;
				if (s[p + 1] == '^') {
					p += 2, Exp = 0; while (isdigit(s[p])) { Exp = Exp * 10 + s[p] - 48; ++p; }
				}
				else { ++p; }
				if (op == '+')ans += c * pwr[Exp]; else ans -= c * pwr[Exp];
			}
			if (readx == false) { if (op == '+')ans += c; else ans -= c; }
		}
		printf("%d\n", ans);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值