题意:
给出一个形如(P)/D的多项式,其中P是n的整系数多项式,D为整数。
问是否对于所有的正整数n,该多项式的值都是整数。
分析:
可以用数学归纳法证明,若P(n)是k次多项式,则P(n+1) - P(n)为k-1次多项式。
P是n的一次多项式时,P是一个等差数列,只要验证P(1)和P(2)是D的倍数即可。
P是n的二次多项式时,只要验证第一项为D的倍数,且相邻两项的差值也是D的倍数即可。相邻两项的差值为一次多项式,所以要验证两项,加上前面验证的第一项,所以共验证P(1)、P(2)和P(3)三项。
一般地,要验证k次多项式,只要验证P(1)...P(k+1)即可。
计算多项式的值可以用高中数学课本讲到过的秦九韶算法。
1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 #include <cstring> 5 #include <cstdlib> 6 using namespace std; 7 8 const int maxn = 100 + 10; 9 int a[maxn], p;//a[i]表示n^i对应的系数,p为最高系数 10 11 void parse_polynomial(string s) 12 { 13 int i = 0, len = s.size(); 14 while(i < len) 15 { 16 int sign = 1; 17 if(s[i] == ‘+‘) i++; 18 if(s[i] == ‘-‘) { i++; sign = -1; } 19 int v = 0;//系数 20 while(i < len && isdigit(s[i])) v = v * 10 + s[i++] - ‘0‘; 21 v *= sign; 22 if(i == len) a[0] = v;//常数项 23 else 24 { 25 if(v == 0) v = sign; 26 int u = 1;//没有指数 27 if(s[++i] == ‘^‘)//有指数 28 { 29 u = 0; 30 i++; 31 while(isdigit(s[i])) u = u * 10 + s[i++] - ‘0‘; 32 } 33 a[u] = v; 34 if(u > p) p = u; 35 } 36 } 37 } 38 39 int mod(int x, int MOD) 40 { 41 int ans = 0; 42 for(int i = p; i >= 0; i--) 43 { 44 ans = (long long) ans * x % MOD;//注意不要溢出 45 ans = ((long long) ans + a[i]) % MOD; 46 } 47 return ans; 48 } 49 50 bool check(string& expr) 51 { 52 int p = expr.find(‘/‘); 53 parse_polynomial(expr.substr(1, p-2)); 54 int D = atoi(expr.substr(p+1).c_str()); 55 for(int i = 1; i <= p+1; i++) 56 if(mod(i, D) != 0) return false; 57 return true; 58 } 59 60 int main() 61 { 62 //freopen("in.txt", "r", stdin); 63 64 int kase = 1; 65 string expr; 66 while(cin >> expr) 67 { 68 if(expr[0] == ‘.‘) break; 69 memset(a, 0, sizeof(a)); 70 p = 0; 71 printf("Case %d: %s\n", kase++, check(expr) ? "Always an integer" : "Not always an integer"); 72 } 73 74 return 0; 75 }
代码君
时间: 2024-10-08 11:13:00