诡秘的余数 (zjutoj)

http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1010

模拟过程代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void work(char *str,int len,int m)
{
    int i,n;
    for(i=0,n=0;i<len;i++)
    {
        n=n*10+str[i]-'0';
        if(n<m) continue;
        n%=m;
    }
    printf("%d\n",n);
}
int main()
{
    int m;
    char str[2000];
    while(~scanf(" %s %d",str,&m))
        work(str,strlen(str),m);
    return 0;
}

规律的代码:

/*1 余数始终为 0
2 10%2=0,偶数为0;奇数为1
3 10%3=1,各位数数字累加再取3的余数
4 100%4=0,故取末两位数对4的余数
5 10%5=0,故取个位数对5的余数
6 分别计算对2、3的余数,再孙子定理
7 10^6%7=1,故从后向前每6位分段累加再取7的余数
8 1000%8=0,故取末三位数对4的余数
9 10%9=1,各位数数字累加再取9的余数*/


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int work(char *str,int n,int m)
{
    if(n<=6)
     return atoi(str)%m;
    switch(m)
    {
        case 2: case 4: case 5: case 8:
        return atoi(str+n-4)%m;
        case 3: case 6: case 7: case 9:
        {
            int x=0;
            char *p=str+n-6;
            for(;p>str;*p='\0',p-=6)
              x+=atoi(p);
            x+=atoi(str);
            return m==6?(3*((str[n-1]-'0')&1)+4*(x%3))%6:x%m;//m为6时不明白。
        }
    }
    return 0;
}
int main()
{
    int m;
    char str[2000];
    while(~scanf(" %s %d",str,&m))
    {
        m=work(str,strlen(str),m);
        printf("%d\n",m);
    }
    return 0;
}



 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值