G - Strange Limit
Consider sequence an defined with thefollowing recurrence:
a1= p,
an+1= pan for n >= 1,
where p issome prime number. Let
bn = an modm!,
where m! denotes m factorial,that is m! = 1 · 2 · ... · m.
It may seem strange, but for all p andall m the sequence bn has limit as n . Your task is to find it. Given p and m,find
Input
There are severaltest cases in the input. Each case contains p and m ( 2<= p, m <= 12, p is prime). There is am empty linebetween each case.
Output
Output the limitrequested. There should be am empty line between each case.
Example
Input | Output |
2 2 | 0 |
2 3 | 4 |
3 8 | 30267 |
题意:输入一个素数p和一个数字m(2<=m<=12),a1=p,an=pan-1,bn= an%m!(bn等于an对m的阶乘取余数),n取正无穷,当计算到一个n时,继续计算bn能够使bn不在改变,输出此时的bn。
思路:先写一个代码用于计算应该输出的bn,题目数据最多5*11组,算出所有可能,打表即可。
打表代码:
#include<stdio.h>
#include<string.h>
long long m;
long long w(long long n)//计算阶乘
{
long long i,sum=1;
for(i=1;i<=n;i++)
{
sum*=i;
}
return sum;
}
long long s(long long p,long long n)//计算an
{
long long i,sum=1; //printf("%d\n",m);
for(i=1;i<=n;i++)
{
sum*=p;
if(sum>m)//不加这个判断会使sum超出long long 范围
sum=sum%m;
}
return sum;
}
int main()
{
long long i,j,k,n,p;
long long a1,b1,t1,t2;
long long a[10]={2,3,5,7,11};//用于计算的素数
for(k=0;k<=4;k++)
{
for(j=1;j<=12;j++)
{
a1=p=a[k];n=1e9;//n赋一个较大的值
m=j;
// printf("m=====%lld\n",m);
// printf("n=====%lld\n",a1);
m=w(m);
t2=0;
for(i=1;i<=n;i++)
{
a1=s(p,a1);
t1=a1%m;//printf("%lld %lld\n",t1,t2);
if(t1==t2)//判断前后是否相等
{
break;
}
t2=t1;
}
printf("%lld,",t1);
}
printf("\n");
}
return 0;
}
提交代码:
#include<stdio.h>
int main()
{
int p,n,z=1;
int a[20][20]={
{0,
0,
4,
16,
16,
16,
16,
25216,
186496,
1275136,
26676736,
106510336, /*p=2时*/
},
{
0,
1,
3,
3,
27,
27,
27,
30267,
151227,
2691387,
31721787,
430889787, /*p=3时*/
}
,
{
0,
1,
5,
5,
5,
245,
3125,
23285,
345845,
708725,
18852725,
18852725, /*p=5时*/
}
,
{
0,
1,
1,
7,
103,
583,
2023,
17143,
339703,
1428343,
8685943,
208269943, /*p=7时*/
}
,
{
0,
1,
5,
11,
11,
131,
2291,
2291,
244211,
244211,
244211,
119994611,} /*p=11时*/
};//储存打表结果,写这题时着急提交,当时提交时没有改一下格式
while(scanf("%d%d",&p,&n)!=EOF)
{
if(z!=1)
{
printf("\n");//注意输出格式,提交PE了两回,尴尬
}
z++;
if(p==2)
{
printf("%d\n",a[0][n-1]);
}
if(p==3)
{
printf("%d\n",a[1][n-1]);
}
if(p==5)
{
printf("%d\n",a[2][n-1]);
}
if(p==7)
{
printf("%d\n",a[3][n-1]);
}
if(p==11)
{
printf("%d\n",a[4][n-1]);
}
}
return 0;
}