ACM: uva 1069 -&n…

Always an integer

Combinatorics is a branch of mathematics chiefly concerned with counting discrete objects. For instance, how many ways can you pick two people out of a crowd of n  n  1×1  n×n 

\epsfbox{p4119.eps}

Many questions like these have answers that can be reduced to simple polynomials in n  n(n - 1)/2  (n$\scriptstyle \wedge$2 - n)/2  (n$\scriptstyle \wedge$4 - 6n$\scriptstyle \wedge$3 + 23n$\scriptstyle \wedge$2 - 18n + 24)/24  n(n + 1)(2n + 1)/6  (2n$\scriptstyle \wedge$3 + 3n$\scriptstyle \wedge$2 + n)/6 

These polynomials are answers to questions that can have integer answers only. But since they have fractional coefficients, they look as if they could produce non-integer results! Of course, evaluating these particular polynomials on a positive integer always results in an integer. For other polynomials of similar form, this is not necessarily true. It can be hard to tell the two cases apart. So that, naturally, is your task.

Input 

The input consists of multiple test cases, each on a separate line. Each test case is an expression in the form (P)/D  P  D  P  Cn$\scriptstyle \wedge$E  C  E 

  1. E  0$ \le$E$ \le$100  E  Cn$\scriptstyle \wedge$E  C  E  Cn$\scriptstyle \wedge$E  Cn  C  Cn$\scriptstyle \wedge$E  n  n 

  2. C  C  E  Cn$\scriptstyle \wedge$E  n$\scriptstyle \wedge$E  n$\scriptstyle \wedge$E 

  3. Only non-negative C 

  4. Exponents in consecutive terms are strictly decreasing.

  5. C  D 

See the sample input for details.

Input is terminated by a line containing a single period.

Output 

For each test case, print the case number (starting with 1). Then print `Always an integer' if the test case polynomial evaluates to an integer for every positive integer n Not always an integer' otherwise. Print the output for separate test cases on separate lines. Your output should follow the same format as the sample output.

Sample Input 

(n^2-n)/2 

(2n^3+3n^2+n)/6

(-n^14-11n+1)/3
.

Sample Output 

Case 1: Always an integer 
Case 2: Always an integer
Case 3: Not always an integer

题意: 判断多项式是否恒为整数.


解题思路:

         1. 代入1~k+1判断是否能整除即可. k是多项式最高项的次数.

         2. 训练指南上有详细的数学归纳法证明.


代码:

#include
#include
#include
using namespace std;
#define MAX 3100
typedef long long ll;

struct node
{
    int c, e;
    bool flag;
}a[110];

char str[MAX];
char ch[15];
int D;

inline int max(int a, int b)
{
    return a > b ? a : b;
}

ll getValue(int num, int value, int D)
{
    ll ans = 1;
    for(int i = 0; i < a[num].e; ++i)
        ans = ans*value%D;
    ans = ans*a[num].c%D;
    return a[num].flag ? ans : -ans;
}

bool judge(int value, int D, int num)
{
    ll ans = 0;
    for(int i = 0; i < num; ++i)
        ans = (ans+getValue(i, value, D))%D;
    return ans == 0;
}

int main()
{
//    freopen("input.txt", "r", stdin);
    int num = 1;
    while(scanf("%s", str) != EOF)
    {
        if(str[0] == '.') break;
       
        int len = strlen(str);
        int index = 0;
        while(str[index] != '(') index++;
        index++;
       
        int cur = 0, maxn = 0;
        while( str[index] != ')' )
        {
            if(cur == 0) //flag
            {
                a[cur].flag = true;
                if(str[index] == '-')
                {
                    a[cur].flag = false;
                    index++;
                }
            }
            else
            {
                a[cur].flag = (str[index] == '+');
                index++;
            }
           
            // number;
            a[cur].c = 1;
            if(str[index] != 'n')
            {
                int temp = 0;
                while( str[index+temp] >= '0' && str[index+temp] <= '9' )
                {
                    ch[temp] = str[index+temp];
                    temp++;
                }
                ch[temp] = '\0';
                sscanf(ch, "%d", &a[cur].c);
                index += temp;
            }
           
            if(str[index] == ')' || str[index+1] == ')')
            {
                a[cur].e = 0;
                if(str[index+1] == ')')
                {
                    a[cur].e = 1;
                    index++;
                }
                cur++;
                break;
            }
           
            index++;
            a[cur].e = 1;
            if(str[index] == '^')
            {
                index++;
                int temp = 0;
                while( str[index+temp] >= '0' && str[index+temp] <= '9' )
                {
                    ch[temp] = str[index+temp];
                    temp++;
                }
                ch[temp] = '\0';
                sscanf(ch, "%d", &a[cur].e);
                index += temp;
            }
           
            maxn = max(maxn, a[cur].e);
            cur++;
        }
       
        index += 2;
        sscanf(str+index, "%d", &D);
        int ans = 0;
        for(int k = 1; k <= maxn+1; ++k)
        {
            if( !judge(k, D, cur) )
            {
                ans = 1;
                break;
            }
        }
       
        if( ans == 0 ) printf("Case %d: Always an integer\n", num++);
        else printf("Case %d: Not always an integer\n", num++);
    }
    return 0;
}




















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值