乐乐是一个聪明而又勤奋好学的孩子。他总喜欢探求事物的规律。一天,他突然对数的正整数次幂产生了兴趣。 众所周知,2的正整数次幂最后一位数总是不断的在重复2,4,8,6,2,4,8,6……我们说2的正整数次幂最后一位的循环长度是4(实际上4的倍数都可以说是循环长度,但我们只考虑最小的循环长度)。类似的,其余的数字的正整数次幂最后一位数也有类似的循环现象: 输入 输入只有一行,包含两个整数n(1 <= n < 10100)和k(1 <= k <= 100),n和k之间用一个空格隔开,表示要求n的正整数次幂的最后k位的循环长度。 输出 输出一行,这一行只包含一个整数,表示循环长度。如果循环不存在,输出-1。 样例输入 32 2 样例输出 4 提示 对于30%的数据,k <= 4; 对于全部的数据,k <= 100。
n表示长度 k表示幂数
内存超限%91
// #include<iostream> using namespace std; int test(string a){ int len=a.length(); int tag=0;//标记无循环 string str=" ",arr; //测试 1...n/2 for(int i=1;i<=(len-1)/2;i++){ str=" "; if((len-1)%i!=0) continue; else { arr=a.substr(1,i); for(int j=1;j<=(len-1)/i;j++){ str+=arr; if(str==a) { return i; } } } } return len-1; } int main() { int m,n,t; string s; char arr; while(cin>>m>>n){ s.clear(); n=n%10; t=1; for(int i=0;i<m;i++){ t*=n; t%=10; arr=t+'0'; s+=arr; } s=' '+s; cout<<test(s)<<endl; } }
参考答案:
#include<iostream> #include<cstring> #include<cstdio> #include<string> #include<algorithm> using namespace std; string s; int m, k; int i, j; int a[205], aans[205], n[205], ans[205], last[205], now[205], t[205]; int single_j[12] = { 1,1,4,4,2,1,1,4,4,2 };//单循环结 void init() { memset(a, 0, sizeof a); memset(last, 0, sizeof last); memset(aans, 0, sizeof aans); memset(now, 0, sizeof now); memset(ans, 0, sizeof ans); memset(n, 0, sizeof n); memset(t, 0, sizeof t); //for (int i = 1;; i++) { if (m == 0) break; n[i] = m % 10; m /= 10; }//将m存入数组n,以便于高精度 } void multiplyh(int x[], int y[], int z[]) {//高精度高乘 int up = 0; for (int ii = 1; ii <= k; ii++) { for (j = 1; j <= k; j++) { z[ii + j - 1] += (x[j] * y[ii] + up) % 10; up = (x[j] * y[ii] + up) / 10; } up = 0; } for (int ii = 1; ii <= k; ii++) {//进位 z[ii + 1] += z[ii] / 10; z[ii] %= 10; } } void multiplyl(int x[], int yy, int z[]) {//高精度低乘 int up = 0; for (int ii = 1; ii <= k; ii++) { z[ii] = (x[ii] * yy + up) % 10; up = (x[ii] * yy + up) / 10; } } int main() { //scanf("%d%d", &m, &k); init(); cin >> s; cin >> k; int temp = 0, len = s.size(); for (i = len - 1; i >= len - k; i--) n[++temp] = s[i] - '0'; int tmp = 0; for (int i = 1; i <= k; i++) ans[i] = n[i]; for (int i = 1; i < single_j[n[1]]; i++) { memset(aans, 0, sizeof aans); multiplyh(ans, n, aans); for (int j = 1; j <= k; j++) { ans[j] = aans[j]; }//更新为第一次出现末尾循环节的状态 } t[1] = single_j[n[1]];//最低位的循环结 for (int i = 1; i <= k; i++) now[i] = ans[i]; int pos = 2;//当前倒数位数 while (pos <= k) { for (int j = 1; j <= k; j++) { ans[j] = n[j]; last[j] = now[j]; } tmp = 0; while (tmp < 11) { tmp++; memset(aans, 0, sizeof aans); multiplyh(ans, now, aans); for (j = 1; j <= k; j++) { ans[j] = aans[j]; } if (ans[pos] == n[pos]) break;//找到循环结 memset(aans, 0, sizeof(aans)); multiplyh(last, now, aans);//更新last for (j = 1; j <= k; j++) last[j] = aans[j]; } if (tmp >= 11) { cout << -1; return 0; } for (int j = 1; j <= k; j++) now[j] = last[j]; memset(aans, 0, sizeof aans); multiplyl(t, tmp, aans);//更新循环节数组 for (int i = 1; i <= 100; i++) t[i] = aans[i]; pos++; } int flag = 0;//不输出前导0 for (int i = 100; i >= 1; i--) { if (t[i]) flag = 1; if (flag) cout << t[i]; } return 0; }
https://www.cnblogs.com/caiyishuai/p/8585886.html