noip2005 循环 (高精度+模拟)
来源:互联网 发布:2017盒子看电影软件 编辑:程序博客网 时间:2024/04/28 23:45
众所周知,2的正整数次幂最后一位数总是不断的在重复2,4,8,6,2,4,8,6……我们说2的正整数次幂最后一位的循环长度是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的正整数次幂来说,它的后k位是否会发生循环?如果循环的话,循环长度是多少呢?
注意:
1. 如果n的某个正整数次幂的位数不足k,那么不足的高位看做是0。
2. 如果循环长度是L,那么说明对于任意的正整数a,n的a次幂和a + L次幂的最后k位都相同。
对于全部的数据,k <= 100。
解析:我直接举一个例子进行说明吧:111 3(由于1的循环长度就是1,所以我直接从末两位循环开始)
我们来看111的末两位循环:
111 -> 321 -> 631 -> 041 -> 551 -> 161 -> 871 -> 681 -> 591 -> 601 -> 711
711处末两位出现循环,循环长度为10,循环节为11-> ...-> 01
现在我们再来看末三位循环:
111->...->601 (10个数)
711->...->201 (201就是601^2的末三位)
311->...->801 (801就是601^3的末三位)
911->...->401 (401就是601^4的末三位)
511->...->001 (001就是601^5的末三位)
111->...->601 (601就是601^6的末三位)
末三位的循环长度就是5*10=50;
好了,现在来讲具体的做法,并假设我们现在求数字n的后k位循环。
朴素的做法就是直接求n^2,n^3,n^4.。。。,并判断是否出现循环。但观察上面的演示例子,我们发现可以不必这样,以n=111为例,末两位循环节长度为10,即表示n与(n^10)*n的末两位是相同的。对于末三位的循环,肯定是(m*n^10),即m*(n^10)与n^10的末三位是相同的,m*(n^10)*n的末三位与n相同。 于是,计算末三位循环的时候,我们就直接将n^10作为第一个数,然后每次乘n^10,共乘5次,末三位出现循环,即m=5,所以末三位循环街长度就为5*10=50。
代码:
#include<cstdio>#include<algorithm>#include<cstdlib>#include<cstring>using namespace std;const int maxn=100;int n,a[maxn+10],b[maxn+10];int c[2][maxn+10],ans[maxn+10];char s[maxn+10];bool same(int p[],int q[],int x){ for(int i=1;i<=x;i++)if(p[i]!=q[i])return 0; return 1;}void multi_1(int x){ int i,last=0; for(i=1;i<=ans[0];i++) { ans[i]=ans[i]*x+last; last=ans[i]/10,ans[i]%=10;} if(last>0)ans[++ans[0]]=last;}void multi_2(int w[],int p[],int q[]){ int i,k,last=0; w[0]=min(p[0]+q[0]-1,n); for(k=1;k<=w[0];k++) { for(w[k]=last,i=1;i<=p[0];i++) if(k+1-i>=1 && k+1-i<=q[0])w[k]+=p[i]*q[k+1-i]; last=w[k]/10,w[k]%=10; } if(last)w[++w[0]]=last;}int get(int x){ memcpy(c[0],b,sizeof(b)); for(int i=1;i<=10;i++) { multi_2(c[i%2],c[(i+1)%2],b); if(same(c[i%2],b,x)) { multi_2(c[i%2],c[(i-1)%2],a); if(!same(c[i%2],a,x))goto d1; memcpy(b,c[(i-1)%2],sizeof(c[0])); return i;}} d1:printf("-1\n"); exit(0);}int main(){ int i; scanf("%s%d",s,&n); a[0]=strlen(s),n=min(a[0],n); for(i=1;i<=n;i++)a[i]=s[a[0]-i]-'0'; memcpy(b,a,sizeof(a)),ans[0]=1,ans[1]=1; for(i=1;i<=n;i++)multi_1(get(i)); for(i=ans[0];i>=1;i--)printf("%d",ans[i]); return 0;}
- noip2005 循环 (高精度+模拟)
- 【NOIP2005普及组T4】循环-高精度
- noip2005 篝火晚会 (模拟)
- 循环(NOIP2005普及组第四题)
- NOIP2005普及组 循环
- 【模拟】篝火晚会(noip2005)
- vijos循环(高精度)
- NOIP2005 等价表达式(栈模拟简单计算器)
- noip2005 谁拿了最多奖学金 (模拟)
- noip2005谁拿最多奖学金(模拟)题解
- [NOIP2005][CODEVS1106]篝火晚会(模拟+数学相关)
- noip2005 陶陶摘苹果 (模拟)
- CodeVS 1107 等价表达式【NOIP2005】【模拟
- ACM模拟题讲解(1)-高精度
- ACM模拟题讲解(1)-高精度
- HDU 1042 N! (模拟 高精度)
- stm32模拟串口(基于高精度延时)
- POJ 1405 Heritage(模拟+高精度乘法)
- Android APK反编译就这么简单 详解(附图)
- 类、对象、继承、封装、多态、方法的重载和重写、Java的访问修饰符与其它关键字
- POJ1039Pipe【线段相交判断+求交点】
- 好汉不吃眼前亏
- Service生命周期
- noip2005 循环 (高精度+模拟)
- 标准会话管理器——StandardManager
- java.sql.Blob类型如何插入到MySQL数据库
- 姿态结算相关-----姿态的表示和传感器
- leetcode[242] Valid Anagram
- 敢不敢不求安稳,去探寻“未知”?
- Erdas的Model Maker功能
- 操作系统为什么要分用户态和内核态
- ImageView之scaleType属性