原题链接:循环
此题需要对余数乘方的深刻理解
解题思路:
总体思路:
N位的循环节长度是 N-1的循环节长度的倍数.
所以,
1位的长度是5的话,
2位的长度就一定是5的倍数,比如25
3位的长度就一定是25的倍数,比如75
要注意的是,1,2,3位的循环节长度可能一致,比如长度都是5,这个是符合规律的
测试高位的循环节,可以每间隔低位循环节的次数测试一次,
最多测试10次,就应该出现循环,否则就是没有循环.
在低次出现循环节时候,记录此时的结果,
后面可以直接乘此结果,相当于次方增加[低位循环节长度的]次数.
参考代码:
#include<stdio.h> #include <string.h> //小端格式 value 增加一个值 addv void char_add(char* value,char addv, int len) { for(int i=0; i0; i++) { int temp = value[i]+addv; value[i] = temp%10; addv = temp/10; } } //product = (yushu*n) % pow(10,k); 小端格式的数据 void calculate(char* yushu, char* n, char* product, int k) { memset(product,0,sizeof(char)*k); char temp; for(int i = 0; i < k; i++) { for(int j = 0; j < k; j++) { if(i+j<k) { temp = yushu[i] * n[j]; char_add(product+i+j, temp, k-i-j); } } } } //输出大端格式的数字 void char_printf_big(char* c, int len) { for(int i=0; i= i; j--, i++) { char tempnumber = number[j]; number[j] = number[i] - '0'; number[i] = tempnumber - '0'; } char originalyushu[MAXBIT]; memset(originalyushu,0,MAXBIT); memcpy(originalyushu, number, k); char yushu[MAXBIT],product[MAXBIT]; int N=1; //正在计算循环节长度的位数 //yushu 保存每次计算的结果 //小端格式 memcpy(yushu, number, k); //1次方的结果 //totaltimes = 累计运算了多少次方 //大端格式 char totaltimes[MAXBIT]; memset(totaltimes,0,sizeof(totaltimes)); totaltimes[MAXBIT-1]=1; //初始1次方 //前一个位数循环节长度 //大端格式 char preN_Times[MAXBIT]; memset(preN_Times,0,sizeof(preN_Times)); preN_Times[MAXBIT-1]=1; //初始循环节长度位1 //mulv 保存每次计算要乘的数,就是 输入的 number 的 preN_Times 次方的余数 //小端格式 char mulv[MAXBIT]; memcpy(mulv, number, k); //初始化位1次方的余数 int TestTimes = 10; //测试10次,没有相同的就是没有循环节 while(TestTimes--) { //使用原始数据相乘,但不保存结果到yushu, 查看下一次方是否出现循环节了 calculate(yushu, number, product, k); //这里用if而不是while的话,在N和N+1的循环长度一样的情况下会出问题 //while(!memcmp(product, originalyushu, N)) while(product[N-1]==originalyushu[N-1]) //本质是上个语句,这样效率更高 { if(N==k) { char_printf_big(totaltimes,MAXBIT); return 0; } N++; //前一个位数循环节长度 memcpy(preN_Times, totaltimes, MAXBIT); //保存每次计算要乘的数 memcpy(mulv, yushu, MAXBIT); TestTimes = 10; //测试次数重新计算 // N 加完以后,不要马上计算下一组,要继续测试新的N是否相等, } //进入下一组数据,相当于次方增加preN_Times次. calculate(yushu, mulv, product, k); memcpy(yushu,product,k);//保存结果到yushu add_big2(totaltimes, preN_Times, MAXBIT); } printf("-1"); return 0; }
0.0分
5 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复