這個題目有很多高手都討論過了,不過都不夠詳細,我就談談怎樣解的吧。
開始我用的是模擬,這樣有3個是超時的,於是我就手工模擬,比如:
a b c d e f
a+b b+c c+d d+e e+f
a+2b+c b+2c+d c+2d+e d+2e+f
a+3b+3c+d b+3c+3d+e c+3d+3e+f
a+4b+6c+4d+e b+4c+6d+4e+f
我們居然看到了熟悉的楊輝三角,熟悉二項式定理的人都知道,每一項的係數是C(0,n-2),C(1,n-2),...,C(n-2,n-2),而我們的問題就是求這些係數的個位。
如果直接計算,時間和空間都不夠,不過我們可以發現,C(i,n-2)/C(i-1,n-2)=(n-i-1)/i,再利用某些人說的分解法就行了。我的方法是把n-i-1和i中的所有2和5提取出來單獨處理,然後求解個位。容易看到,兩個已知個位的奇數的商的個位是一定的(不過5的倍數會造成干擾)。
因此,程序就出來了,容易得知這個算法的複雜度爲O(NlogN).以下程序在10個測試點中均只用了不到100ms:
- #include <stdio.h>
- #include <string.h>
- int f(int m,int n)
- {
- if (n==1) return m;
- if (n==3)
- switch (m)
- {
- case 1:return 7;
- case 3:return 1;
- case 7:return 9;
- case 9:return 3;
- }
- if (n==7)
- switch (m)
- {
- case 1:return 3;
- case 3:return 9;
- case 7:return 1;
- case 9:return 7;
- }
- if (n==9)
- switch (m)
- {
- case 1:return 9;
- case 3:return 7;
- case 7:return 3;
- case 9:return 1;
- }
- }
- int main()
- {
- char a[100004];
- int s,n,i,n2=0,n5=0,r=1,t1=0,t2=0,c[4]={6,2,4,8},tmp1,tmp2,tmp3;
- scanf("%s",a);
- n=strlen(a);
- for (i=0;i<n;i++) a[i]-='0';
- t1=a[0]+a[n-2];
- t2=a[1]+a[n-1];
- for (i=1;i<=n/2-1;i++)
- {
- tmp1=n-i-1;tmp2=i;
- while (tmp1%2==0) {n2++;tmp1/=2;}
- while (tmp1%5==0) {n5++;tmp1/=5;}
- while (tmp2%2==0) {n2--;tmp2/=2;}
- while (tmp2%5==0) {n5--;tmp2/=5;}
- r*=tmp1;
- r=f(r%10,tmp2%10);
- if (n5!=0)
- {
- if (n2!=0) tmp3=0;
- else tmp3=5;
- }
- else if (n2!=0) tmp3=r*c[n2%4]%10;
- else tmp3=r;
- t1+=(a[i]+a[n-2-i])*tmp3;
- if (t1>10000000) t1%=10;
- t2+=(a[i+1]+a[n-1-i])*tmp3;
- if (t2>10000000) t2%=10;
- }
- if (n%2==0)
- {
- i--;t1+=1000;t2+=1000;
- t1-=a[i]*tmp3;
- t2-=a[i+1]*tmp3;
- }
- t1%=10;t2%=10;
- s=t1*10+t2;
- if (s==0) s=100;
- printf("%d",s);
- }
總結——出現錯誤時需要換個思想紙上驗證