• 循环 未理解


    乐乐是一个聪明而又勤奋好学的孩子。他总喜欢探求事物的规律。一天,他突然对数的正整数次幂产生了兴趣。
    众所周知,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;
        }
    } 
    View Code

     参考答案:

    #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;
    }
    View Code

     https://www.cnblogs.com/caiyishuai/p/8585886.html

     
  • 相关阅读:
    windows运行shell脚本
    Android Webview H5资源本地化
    Vscode开发Python环境安装
    Vscode开发Java环境搭建
    为什么索引可以提高效率?
    Java内存模型
    栈和队列----向有序的环形单链表中插入新节点
    栈和队列----单链表的选择排序
    栈和队列----将搜索二叉树转换成双向链表
    栈和队列----在单链表中删除指定值的节点
  • 原文地址:https://www.cnblogs.com/helloworld2019/p/10412604.html
Copyright © 2020-2023  润新知