CSU OJ:1347 Last Digitn(找規律||找週期+快速冪)
阿新 • • 發佈:2019-02-20
Source
中南大學第一屆長沙地區程式設計邀請賽
解題思路:這種題一般都有周期,我把它的前200*200的表打了出來,發現它的列週期為4,行週期為100.這麼一來,把他的100*4的表暴力寫出來,然後對於n,k取餘然後對映到打好的表即可。
程式碼如下:
#include <cstdio> int m[101][5]; int quickpow(int a,int b) { int ans=1; int base=a%10; while(b) { if(b&1) { ans=(ans*base)%10; } base=(base*base)%10; b=(b>>1); } return ans; } int main() { for(int n=1;n<=100;n++) { for(int k=1;k<=4;k++) { for(int i=1;i<=n;i++) { m[n][k]=(m[n][k]+quickpow(i,k))%10; } } } /*for(int i=1;i<=200;i++)//打表後發現橫著的迴圈節長度為4,縱向的迴圈節長度為100 { for(int j=1;j<=4;j++) { printf("%d ",m[i][j]); } printf("\n"); } */ int t; scanf("%d",&t); while(t--) { int n,k; scanf("%d%d",&n,&k); if(n>100) { n=n%100; } if(n==0)//比如n剛開始為200,那麼它對應表中的100,但是取餘時變成了0 { n=100; } if(k>4) { k=k%4; } if(k==0)//同上 { k=4; } printf("%d\n",m[n][k]); } return 0; }
上面這種方法是離線打表的,比較快。還有網上的一種方法是找具體每次輸入的n,k先打個大概的表,然後找表所對應的迴圈節,然後對映到打好的表輸出答案:
/*該程式碼來自http://blog.csdn.net/aaaaacmer/article/details/44754637*/ #include<stdio.h> #include<string.h> int powermod(int a,int b) { int ans=1; a=a%10; while(b>0) { if(b%2==1)ans=(ans*a)%10; b=b/2; a=(a*a)%10; } return ans; } int main() { int n,k,i,j,f[1111],T,flag,x,temp; scanf("%d",&T); while(T--) { memset(f,0,sizeof(f)); scanf("%d%d",&n,&k); for(i=1;i<=1000;i++)//打個大概的表 { f[i]=(f[i-1]+powermod(i,k))%10; } for(i=1;i<=1000;i++)//列舉迴圈節長度 { flag=1; for(j=i+1;j<=1000;j++)//判斷所列舉的迴圈節是否正確 { if(f[j%i]!=f[j]) { flag=0;break; } } if(flag) { x=i;break; } } f[0]=f[x];//避免整除的那種 temp=n%x;//找到對應表中的位置 printf("%d\n",f[temp]); } return 0; }