Swust 485 自守数 / Poj 2205 Self-Replicating Numbers

来源:互联网 发布:最新犀牛软件下载 编辑:程序博客网 时间:2024/04/30 22:11

题目连接:

第一题:http://acm.swust.edu.cn/oj/problem/485/

第二题:http://poj.org/problem?id=2205

两题都是自守数问题。

第一题是简单的十进制的自守数判断:

以376为例
376 被乘数
X 376 乘数
----------
2256 第一个部分积=被乘数*乘数的倒数第一位
2632 第二个部分积=被乘数*乘数的倒数第二位
1128 第三个部分积=被乘数*乘数的倒数第三位
----------
141376 积
本问题所关心的是积的最后三位。分析产生积的后三位的过程,可以看出,在每一次的部分积中,并不是它的每一位都会对积的后三位产生影响。总结规律可以得到:在三位数乘法中,对积的后三位产生影响的部分积分别为:
第一个部分积中:被乘数最后三位*乘数的倒数第一位
第二个部分积中:被乘数最后二位*乘数的倒数第二位
第三个部分积中:被乘数最后一位*乘数的倒数第三位
将以上的部分积的后三位求和后截取后三位就是三位数乘积的后三位。这样的规律可以推广到同样问题的不同位数乘积。

代码:

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <vector>using namespace std;int main(){/*#ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);#endif*/    int n;    while(scanf(" %d",&n)!=EOF)    {        //数的位数        int k = 1;        if(n == 0 || n == 1)        {            printf("NO\n");            continue;        }        int temp = n;        while(temp/10!=0)        {            temp /= 10;            k *= 10;        }        //求余的系数        int kk = k*10;        k = kk;        int part = 0;        int mul = 10;        while(k>=10)        {            //被乘数            int a = n%k;            //乘数            int b = ((n - (n/mul)*mul)/(mul/10))*(mul/10);            //部分积            part += (a*b)%kk;            part %=kk;            k /=10;            mul *=10;        }        if(n == part)        {            printf("YES\n");        }        else        {            printf("NO\n");        }    }    return 0;}


第二题要处理N进制K位的自守数求解问题。

对所有情况从低位到高位搜索遍历即可。

参考:http://hi.baidu.com/yxdark/item/3b4648c7dd0e0a57bcef6948


#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <vector>#include <algorithm>using namespace std;struct Node{    char self[2005];};Node p[1000];int a[2005];int m;int b,n;char Change(int x){    if (x<=9)        return '0'+x;    else        return 'A'+x-10;}//从低位往高位搜索void dfs(int dep,int sum){    if(dep>n)    {        if(a[n]>0 || n == 1)        {            for(int i=n; i>=1; i--)            {                p[m].self[n-i] = Change(a[i]);            }            p[m].self[n] = '\0';            m++;        }        return;    }    int tol = 0;    for(a[dep]=0; a[dep]<b; a[dep]++)    {        tol = 0;        for(int i=1; i<=dep; i++)        {            int j = dep-i+1;            tol += a[i]*a[j];        }        if((tol+sum)%b == a[dep])        {            dfs(dep+1,(tol+sum)/b);        }    }}bool cmp(Node a,Node b){    return strcmp(a.self,b.self)<0;}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);#endif    while(scanf(" %d %d",&b,&n)!=EOF)    {        m = 0;        dfs(1,0);        sort(p,p+m,cmp);        printf("%d\n",m);        for(int i=0; i<m; i++)        {            printf("%s\n",p[i].self);        }    }    return 0;}