例题2.8 总是整数 LA4119
1.题目描写叙述:点击打开链接
2.解题思路:本题利用差分序列的性质解决。将1,2,..,k+1都带入表达式计算,假设对全部的i。都有D整除P(i),那么该序列全部值都为整数,否则不都为整数。
由于假设某一项不能整除。那么d^kP(i)就不是整数,因此不总是整数。
只是本题的一个难点在于怎样解析表达式,能够发现。多项式的构成都符合an^k的形式。因此能够对第i项。找到它的系数a[i]和指数p[i],从而成功解析整个表达式。
详细实现细节见代码。
3.代码:
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<algorithm> #include<cassert> #include<string> #include<sstream> #include<set> #include<bitset> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<cctype> #include<functional> using namespace std; #define me(s) memset(s,0,sizeof(s)) #define rep(i,n) for(int i=0;i<(n);i++) typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; typedef pair <int, int> P; struct Polynomial { vector<int>a,p; void parse_polynomial(string expr) { int i=0,len=expr.length(); while(i<len) { int sign=1; if(expr[i]=='+')i++; if(expr[i]=='-'){sign=-1;i++;} int v=0; while(i<len&&isdigit(expr[i]))v=v*10+expr[i++]-'0';//获得完整的系数 if(i==len){a.push_back(v);p.push_back(0);}//常数项 else { assert(expr[i]=='n'); if(v==0)v=1; //假设第一项没有系数,那么当做1 v*=sign; if(expr[++i]=='^')//有指数 { a.push_back(v); v=0; i++; while(i<len&&isdigit(expr[i]))v=v*10+expr[i++]-'0'; p.push_back(v); } else //没有指数。默认指数是1 { a.push_back(v); p.push_back(1); } } } } int mod(int x,int MOD) { int n=a.size(); int ans=0; for(int i=0;i<n;i++) { int m=a[i]; for(int j=0;j<p[i];j++) m=(ll)m*x%MOD; //注意:乘法可能会溢出 ans=((ll)ans+m)%MOD; //加法也可能会溢出 } return ans; } }; bool check(string expr) { int p=expr.find('/'); Polynomial poly; poly.parse_polynomial(expr.substr(1,p-2)); int D=atoi(expr.substr(p+1).c_str()); for(int i=1;i<=poly.p[0]+1;i++) if(poly.mod(i,D)!=0)return false; return true; } int main() { int kase=1; string expr; while(cin>>expr) { if(expr[0]=='.')break; printf("Case %d: ",kase++); if(check(expr))puts("Always an integer"); else puts("Not always an integer"); } }