poj1047

来源:互联网 发布:易酷cms官网 编辑:程序博客网 时间:2024/05/21 18:37

题目不难。高精度乘法运算+判断循环数

给定一个长度为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 1000char 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);elseprintf("%s is not cyclic\n",Input);}return 0;}


 

0 0