UVA1069 题解

UVA1069 题解

题意:

输入一个形如 \((P)/D\) 的多项式,判断其是否总是为整数。

多项式最高次次数不超过 \(100\),其他数均属于 \(32\) 位整数范围内。

做法:

我们可以得到有一个性质:

对于一个最高次为 \(k\) 的多项式,我们只需要将 \(x = 1,2,\cdots k+1\) 分别带入多项式并求值,

如果这 \(k+1\) 个点值都是整数,则我们就可以断定这个多项式的整点值总为整数。

对这个性质,我们可以归纳证明:

首先,对一个 \(0\) 次多项式,显然我们只用带一个值 \(x=1\) 即可。

那么,如果对于一个 \(k\) 次多项式 \(F(x)\),其整点值总为整数,

就等价于其差分数组 \(F'(x) = F(x+1)-F(x)\) 的整点值总为整数,

\(F(x)\) 带入 \(x=1\) 时值为整数。

而其差分数组必然是一个 \(k-1\) 次多项式,

我们只需要对差分数组带入 \(x=1,2,\cdots k\),即可证明差分数组的整点值总为整数。

而其差分数组带入 \(x=1,2,\cdots k\) 时为整数,等价于原数组带入 \(x = 1,2,\cdots k+1\) 时为整数。

我们这样做时,已经带入了 \(x=1\) 时的值,故此时 \(F(x)\) 必然总是整数。

那么这个题就解决了。

code:

#include<bits/stdc++.h>
#define LL long long
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
#define per(i, a, b) for (int i = (a); i >= (b); i--)
using namespace std;
const int N (105);
int a[N];
char s[10005];
int main() {
	int cse = 0;
	while (cin >> (s + 1)) {
		if (s[1] == '.') break;
		LL c = 0; cse++;
		printf ("Case %d: ", cse);
		int m = strlen (s + 1), n = -1, mid = m + 1;
		rep (i, 1, m) if (s[i] == '/') mid = i;
		int flg = 1, xa = -1, xb = -1, now = 0, ok = 0;
		rep (i, 2, mid - 1) {
			if (s[i] == '-' || s[i] == '+' || s[i] == ')') {
				if (i != 2) {
					if (xa < 0) xa = 1;
					if (xb < 0) xb = 1;
					if (!ok) xb = 0;
					if (n == -1) n = xb;
					a[xb] = xa * flg, xb = -1, xa = -1;
				}
				ok = 0;
				if (s[i] == ')') continue;
				flg = (s[i] == '-' ? -1 : 1);
				now = 0; continue;
			}
			if (s[i] == '^') {
				now = 1; continue;
			}
			if (s[i] == 'n') {
				ok = 1; continue;
			}
			int &xx = (now ? xb : xa);
			if (xx < 0) xx = 0;
			xx = xx * 10 + s[i] - '0';
		}
		rep (i, mid + 1, m) c = c * 10 + s[i] - '0';
		if (c == 0) c = 1;
        int pl = 0;
		rep (x, 0, 100) {
			LL sum = 0, t = 1;
			per (i, 100, 0) sum = (sum * x + a[i]) % c;
			if (sum != 0) {
				puts ("Not always an integer");
				pl = 1; break;
			}
		}
		if (!pl) puts ("Always an integer");
		memset (a, 0, sizeof(a));
	}
	return 0;
}
posted @ 2021-12-03 16:50  GaryH  阅读(37)  评论(0编辑  收藏  举报