uva1069-数学归纳法

题目链接:https://cn.vjudge.net/problem/UVA-1069

题意:给出一个多项式(P) / D,P = Am * n^m + Am-1 * n^(m-1) + ... + A2 * n^2 + A1 * n + A0, 判断是否对于所有的正整数,其结果都为整数

思路:判断对于所有的正整数,(P) / D 的结果是否都为整数,等价于判断对于所有的正整数,(P) mod D == 0是否恒成立.

题目中给的m(幂)最大为100,可以用试验法来判断(P) / D 的整数性。

只需判断n = 1, 2, 3, ..., m, m + 1时,(P) / D 是否都为整数即可,若都为整数,则对于所有的正整数,(P) / D的结果都为整数,用数学归纳法证明如下:

m = 1时,P(n) = A1*n + A0, 为等差数列, 首项与公差均为D的倍数时,则整个数列为D的倍数, 所以,验证P(1), P(2)即可

假设m = k时,P(n) = Ak * n^k + ... + A2 * n^2 + A1 * n + A0, 验证P(1), P(2), ..., P(k), P(k+1)即可

则m = k + 1时,

P(n) = Ak+1 * n^(k+1) + Ak * n^k + ... + A2 * n^2 + A1 * n + A0

P(n + 1) = Ak+1 * (n+1)^(k+1) + Ak * (n+1)^k + ... + A2 * (n+1)^2 + A1 * (n+1) + A0,

P(n+1) - P(n) = Ak+1 * ((n+1)^(k+1) - n^(k+1)) + Ak * ((n+1)^k - n^k) + ... + A2 * ((n+1)^2 - n^2) + A1 * ((n+1) - n) + A0

                        = Bk * (n+1)^k + Bk-1 * (n+1)^(k-1) + ... + B2 * (n+1)^2 + B1 * (n+1) + B0

验证 P(2) - P(1), P(3) - P(2), ..., P(k+1) - P(k), P(k+2) - P(k+1) 即可,

即验证 P(1), P(2), P(3), ..., P(k), P(K+1), P(K+2),

说明假设成立,证明完毕。


对输入的表达式进行解析,将多项式的每一项系数存起来,然后进行验证即可。

求多项式的值可用秦九韶算法,将复杂度从o(n^2)降到o(n)


代码:

# include <iostream>
# include <algorithm>
# include <cstdio>
# include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 100 + 5;
char s[maxn * maxn];
int a[maxn];
int d;
int maxp;

void f() {
    int len = strlen(s);
    memset(a, 0, sizeof a);
    int sum = 0; char fh = '+';
    int ss = 0; maxp = 0;
    for (int i = 1; i < len; ++i) {
        if (isdigit(s[i])) sum = sum * 10 + s[i] - '0';
        if (s[i] == 'n') {
            if (sum == 0) sum = 1;
            if (fh == '-') sum = -sum;
            if (s[i + 1] != '^') { a[1] = sum; maxp = max(maxp, 1); }
            else {
                for (i += 2; isdigit(s[i]); ++i) ss = ss * 10 + s[i] - '0';
                a[ss] = sum; maxp = max(maxp, ss);
            }
            sum = 0; fh = '+'; ss = 0;
        } else if (s[i] == ')') {
            if (fh == '-') sum = -sum;
            a[0] = sum;
            sum = 0; fh = '+'; ss = 0;
        } else if (s[i] == '/') {
            d = 0;
            for (++i; i < len; ++i) d = d * 10 + s[i] - '0';
        }
        if (s[i] == '-') fh = '-';
    }
}

bool judge(int x) {
    int ys = a[maxp] % d;
    for (int i = maxp - 1; i >= 0; --i) {
        ys = ((ll)ys * x + a[i]) % d;
    }
    return ys == 0;
}

int main(void)
{
    int Case = 0;
    while (~scanf("%s", s)) {
        if (strcmp(".", s) == 0) break;
        f();
        bool ok = true;
        for (int i = 1; i <= maxp + 1; ++i) {
            if (judge(i) == false) { ok = false; break; }
        }
        printf("Case %d: ", ++Case);
        if (ok == true) printf("Always an integer\n");
        else printf("Not always an integer\n");
    }

    return 0;
}

/*
(n^2-n)/2
(2n^3+3n^2+n)/6
(-n^14-11n+1)/3
(-2)/2
(-2)/1
(-2)/3
(n-1)/1
(n-1)/2
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值