题目不难。高精度乘法运算+判断循环数
给定一个长度为n的整数,注意有前导0,并算数字的一部分,若该数字满足:对所有n*pivot=cyclic(n),其中pivot为1、2、……、n数字的长度。cyclic(n)表示n的循环数。则n为循环数,否则不是循环数。
分析如下:首先将数字转化为数组,可有前导0,不影响乘法结果。然后依次枚举每个pivot,进行高精度乘法运算。对运算结果判断是否为n的循环数,若全部都是则说明是循环数,否则不是循环数。
这里,进行高精度乘法运算时要注意一点:
当真实结果(去除前导0)的长度大于n的长度时,则说明一定不是n的循环数;若小于或等于n的长度,则应该补充前导0直至长度相同。
判断循环数其实就是一个取模问题,这里不说明,详见注释:
下面是代码:168K+0MS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Max 1000
char Input[Max]; //输入整数字符串
int trans[Max]; // 将整数字符串转化为整数数组
int midd[Max]; //存储1——n长度之间数 : 转化为整数数组
int result[Max]; //存储乘法结果
int len_trans,len_midd,len_result; //长度
bool Is_circle(){ // 判断是否为循环数,取模是关键
for(int i=0;i<len_trans;i++){ //枚举起点
int j=i,num=0,pivot=0;
while(true){
if(trans[j]!=result[pivot])
break;
else{
num++;
pivot++;
if(num==len_trans)
return true;
j=(j+1)%len_trans; //重点
}
}
}
return false;
}
bool epo(){ //高精度乘法运算
int i,j;
memset(result,0,sizeof(result));
for(i=0;i<len_trans;i++)
for(j=0;j<len_midd;j++)
result[i+j]+=trans[i]*midd[j];
for(i=0;i<Max;i++)
if(result[i]>=10){
result[i+1]+=result[i]/10;
result[i]%=10;
}
for(i=Max-1;i>=0;i--)
if(result[i]>0)
break;
if(i+1>len_trans) // 若实际长度大于n的长度,则一定不是n的循环数
return false;
return Is_circle(); // 否则可以适当补充0,判断是否为循环数
}
bool Is_cyclic(){ //判断n是否为循环数
for(int i=1;i<=len_trans;i++){ //枚举1——n长度数字
int temp=i,pivot=0;
while(temp>0){ //转化为数组
midd[pivot++]=temp%10;
temp/=10;
}
len_midd=pivot;
if(!epo()) //若存在一个不是n的循环数,则说明n不是循环数
return false;
}
return true;
}
int main(){
while(scanf("%s",Input)!=EOF){
getchar();
int len=strlen(Input);
for(int i=len-1;i>=0;i--) //转化为整数数组
trans[len-i-1]=Input[i]-'0';
len_trans=len;
if(Is_cyclic()) //判断是否为循环数
printf("%s is cyclic\n",Input);
else
printf("%s is not cyclic\n",Input);
}
return 0;
}