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