Swust 485 自守数 / Poj 2205 Self-Replicating Numbers
两题都是自守数问题。
第一题是简单的十进制的自守数判断:
以376为例
376 被乘数
X 376 乘数
----------
2256 第一个部分积=被乘数*乘数的倒数第一位
2632 第二个部分积=被乘数*乘数的倒数第二位
1128 第三个部分积=被乘数*乘数的倒数第三位
----------
141376 积
本问题所关心的是积的最后三位。分析产生积的后三位的过程,可以看出,在每一次的部分积中,并不是它的每一位都会对积的后三位产生影响。总结规律可以得到:在三位数乘法中,对积的后三位产生影响的部分积分别为:
第一个部分积中:被乘数最后三位*乘数的倒数第一位
第二个部分积中:被乘数最后二位*乘数的倒数第二位
第三个部分积中:被乘数最后一位*乘数的倒数第三位
将以上的部分积的后三位求和后截取后三位就是三位数乘积的后三位。这样的规律可以推广到同样问题的不同位数乘积。
代码:
[cpp]
#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;
}
#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位的自守数求解问题。
对所有情况从低位到高位搜索遍历即可。
[cpp]
#include <iostream>
#include <stdio.h>
#include <stdlib.h> 补充:软件开发 , C++ ,