此题需要对余数乘方的深刻理解

解题思路:
   总体思路:
   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.0分

5 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论