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;
}