洛谷P1050循环题解--zhengjun

题目描述

乐乐是一个聪明而又勤奋好学的孩子。他总喜欢探求事物的规律。一天,他突然对数的正整数次幂产生了兴趣。

众所周知, 2 2 2的正整数次幂最后一位数总是不断的在重复 2 , 4 , 8 , 6 , 2 , 4 , 8 , 6 … 2,4,8,6,2,4,8,6… 2,4,8,6,2,4,8,6我们说 2 2 2的正整数次幂最后一位的循环长度是 4 4 4(实际上 4 4 4的倍数都可以说是循环长度,但我们只考虑最小的循环长度)。类似的,其余的数字的正整数次幂最后一位数也有类似的循环现象:

    循环    循环长度
2   2,4,8,6   4
3   3,9,7,1   4
4   4,6       2
5   5         1
6   6         1
7   7,9,3,1   4
8   8,4,2,6   4
9   9,1       2

这时乐乐的问题就出来了:是不是只有最后一位才有这样的循环呢?对于一个整数 n n n的正整数次幂来说,它的后 k k k位是否会发生循环?如果循环的话,循环长度是多少呢?

注意:

  1. 如果 n n n的某个正整数次幂的位数不足 k k k,那么不足的高位看做是 0 0 0
  2. 如果循环长度是 L L L,那么说明对于任意的正整数 a , n a,n a,n a a a次幂和 a + L a+L a+L次幂的最后 k k k位都相同。
输入格式

一行,包含 2 2 2个整数 n ( 1 ≤ n < 1 0 100 ) n(1 \le n < 10^{100}) n(1n<10100))和 k ( 1 ≤ k ≤ 100 ) k(1 \le k \le 100) k(1k100) n n n k k k之间用一个空格隔开,表示要求 n n n的正整数次幂的最后 k k k位的循环长度。

输出格式

一个整数,表示循环长度。如果循环不存在,输出 − 1 -1 1

输入输出样例
输入 #1 复制
32 2
输出 #1 复制
4
说明/提示

对于 30 % 30\% 30%的数据, k ≤ 4 k \le 4 k4

对于全部的数据, k ≤ 100 k \le 100 k100

N O I P 2005 NOIP2005 NOIP2005普及组第四题

思路

首先,这道题一定是要高精度的,答案同样。

第一个方法肯定是暴力,知道循环,可是答案都要高精度了能不 T L E TLE TLE

那么,正解就是这样的。

比如说 78910912 78910912 78910912 4 4 4 (第三个数据点)

取后面的四位就是 912 912 912

首先,我们可以求出最后一位的循环长度,很显然是 4 4 4

2,4,8,6,2
        ^

接着,怎么求出后两位的循环长度呢,因为后两位要循环的话必须先让最后一位循环,再看第二位是否循环,那么直接每一次乘上个 4 4 4 ( ( (就是 1 2 4   m o d   100 = 36 ) 12^4\bmod100=36) 124mod100=36),因为 4 4 4次个位才会循环,判断是否循环。

12,32,52,72,92,12
               ^

所以,后面两位要循环就要 20 20 20次,因为个位是一个小循环 4 4 4次,十位是在个位的基础上大循环 5 5 5次。

接下来求后面三位循环, 91 2 20   m o d   1000 = 176 912^{20}\bmod 1000=176 91220mod1000=176

912,512,112,712,312,912
                    ^

五位一循环,所以,后三位的循环长度就是 20 × 5 = 100 20\times5=100 20×5=100

最后就是四位了

91 2 100   m o d   10000 = 3376 912^{100}\bmod 10000=3376 912100mod10000=3376

912,8912,6912,4912,2912,912
                        ^

所以最终的答案就是 500 500 500

代码

#include<bits/stdc++.h>
#define cpy(x,y) for(int v=1;v<=k;v++)x[v]=y[v];
using namespace std;
int xh[11]={1,1,4,4,2,1,1,4,4,2};
int k,b[205],c[205],d[205],p[205],q[205],ans[205],tot1,tot2=2,t;
char a[105];
void mul1(int x[],int y[],int z[]){
    for(int i=1;i<=k;i++){
        for(int j=1;j<=k;j++){
            z[i+j-1]+=x[i]*y[j];
            z[i+j]+=z[i+j-1]/10;
            z[i+j-1]%=10;
        }
	}
}
void mul2(int x[],int y,int z[]){
    for(int i=1;i<=k;i++){
        z[i]+=x[i]*y;
        z[i+1]+=z[i]/10;
        z[i]%=10;
    }
}
int main(){
    scanf("%s%d",a+1,&k);
	int len=strlen(a+1);
    for(int i=len;i>=len-k+1;i--)
	    c[++tot1]=a[i]-'0';
    for(int i=1;i<=k;i++)
	    b[i]=c[i];
    for(int i=1;i<xh[c[1]];i++){
        memset(d,0,sizeof(d));//这个一定要加,如果放在mul1里面就会wa
        mul1(b,c,d);
        cpy(b,d);
    }
    ans[1]=xh[c[1]];
    cpy(q,b);
    cpy(p,b);
    while(tot2<=k){
        cpy(b,c);
        while(t<11){
            memset(d,0,sizeof(d));
            mul1(b,p,d);
            t++;
            cpy(b,d);
            if(b[tot2]==c[tot2])
			    break;
            memset(d,0,sizeof(d));
            mul1(q,p,d);
            cpy(q,d);
        }
        if(t==11){//无解
		    printf("-1");
			return 0;
		}
        cpy(p,q);
        memset(d,0,sizeof(d));
        mul2(ans,t,d);
        for(int i=1;i<=100;i++)//计算答案
		    ans[i]=d[i];
        tot2++;
        t=0;
    }
    int anslen=101;
    while(ans[anslen]==0&&anslen>1)
	    anslen--;
    for(int i=anslen;i>=1;i--)
	    printf("%d",ans[i]);
	return 0;
}

我最后只想说一句,那些用 p y t h o n , j a v a python,java python,java做的不知道比赛不支持吗?

谢谢–zhengjun

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A_zjzj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值