问题 1074: 数字整除【Right】

时间限制: 1Sec 内存限制: 128MB

题目描述

定理:把一个至少两位的正整数的个位数字去掉,再从余下的数中减去个位数的5倍。当且仅当差是17的倍数时,原数也是17的倍数 。
例如,34是17的倍数,因为3-20=-17是17的倍数;201不是17的倍数,因为20-5=15不是17的倍数。输入一个正整数n,你的任务是判断它是否是17的倍数。
输入
输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=10^100),表示待判断的正整数。n=0表示输入结束,你的程序不应当处理这一行。
输出
对于每组测试数据,输出一行,表示相应的n是否是17的倍数。1表示是,0表示否。
样例输入
34
201
2098765413
1717171717171717171717171717171717171717171717171718
0
样例输出
1
0
1
0

代码及分析

这题的思路是如何从给出的定理展开,再来看一遍定理
定理:把一个至少两位的正整数的个位数字去掉,再从余下的数中减去个位数的5倍。当且仅当差是17的倍数时,原数也是17的倍数 。


比如一个数:ab(a是n位正整数,b是个位数)是17的倍数
如果这个数是17倍数,那么有一个一元方程: a + x − ( b % 17 + x ) 17 = 0 \frac{a+x-(b\%17+x)}{17}=0 17a+x(b%17+x)=0成立
前提条件: b % 17 + x 17 = 0 \frac{b\%17+x}{17}=0 17b%17+x=0 恒成立
推出结论: a + x a+x a+x也是17的倍数


根据这个假设方程,推出下面程序的思路
先将这个数字作为字符串存储,然后转化为一个数组(主要是一个一个读数字太麻烦了)
对个位数进行处理,找出处理后与17的差值。将差值加到剩余数的数组的个位数中(可能大于10,但没关系)
然后进行循环处理,每次循环数组将减少最后一位直至数组仅有一个元素(len来控制数组中元素的数量)
最后进行判断仅剩余的数是否是17的倍数。

#include
#include
int main()
{
     
    char s[101];
    int num[101],len,a,i,j=0,input[10];
    while(scanf("%s", s)&&(s[0]-'0')){
     
        len=strlen(s);
        for(i=0;i<len;i++)
            num[i]=s[i]-'0';
        while(len!=1){
     
            a=num[len-1];
            a=17-(a*5)%17;
            if(a==17)   a=0;//最后位的运算缺少数
            len--;
            num[len-1]+=a;
        }
        input[j++]=(num[0]%17==0?1:0);
    }
    for(i=0;i<j;i++)
        printf("%d\n", input[i]);
    return 0;
}

你可能感兴趣的:(OJ练习)