uva1069-数学归纳法

来源:互联网 发布:把ubuntu安装到u盘 编辑:程序博客网 时间:2024/05/19 01:12

题目链接: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*/


原创粉丝点击