题意:
令X0=A,
Xi=(a*Xi-1^2,b*Xi-1+c)%m;
求Xk,(0<=k<=109),(0<=a,b<=100),(1<m<1000);
Solution:
题目的关键在于m的范围,1000的范围显然是会在取余后出现循环的。
只要得出循环的数列的长度以及它的每一个数,和任意一个循环的起点位置。就可以算出Xk 值。
要注意的是X0 是不对m取余的,还有当X0很大时,计算X1 的中间量是有可能超过int范围的。
code:
#include<stdio.h> #include<string.h> int main() { int A, alpha, beta, gamma, M , k; int loop,i,t; int num[1010]; int visit[10100];//注意这里要开10000+虽然用的个数不超过1000个只是因为A<=10000 //visit用来标记是否num[i]的值是否出现过即visit[num[i]]是否是-1 //因为M<1000 所以会在至多1000个数开始出现循环 while(~scanf("%d%d%d%d%d%d",&A,&alpha,&beta,&gamma,&M,&k)) { memset(visit,-1,sizeof(visit)); num[0]=A;visit[A]=0; for(i=1;;i++) { num[i]=alpha*num[i-1]%M*num[i-1]%M+beta*num[i-1]%M+gamma%M; num[i]%=M; if(visit[num[i]]!=-1){ /* loop=i; //i 个开始出现循环 k(i)(visit[num[i]])= 0 1 2 3 4 5 6 7 注意这里这样是错的, 它循环可能是中间出现循环如 (num[i]) 9 7 8 4 5 6 8 4 (6-2) 所以这样记录的个数不是i个, 固修改如下 */ loop=i-visit[num[i]]; //这样loop正好为循环个数 t=visit[num[i]];//表示循环列前面还有的个数 break; } else visit[num[i]]=i; // } if(k<visit[num[i]])printf("%d ",num[k]); //如果k未出现循环 else printf("%d ",num[(k-t)%loop+t]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。