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

你可能感兴趣的:(数论,整除,表达式解析)