1. 先看单个数的规律:(UVA10515一样)
0^n%10: 0
1^n%10: 1
2^n%10: 2,4,8,6
3^n%10: 3,9,7,1
4^n%10: 4,6
5^n%10: 5
6^n%10: 6
7^n%10: 7,9,3,1
8^n%10: 8,4,2,6
9^n%10: 9,1
2. 因为最大循环长度为4,所以我们可以看到,i^i%10和i^(i+20)%10是相同的,也就是说,i^i%10的周期是20
而(1^1+……+20^20)%10=4,
所以(1^1+……+40^40)%10=8,
(1^1+……+60^60)%10=2,
(1^1+……+80^80)%10=6,
(1^1+……+100^100)%10=0,
这么看来,S(N)%10=S(N%100)%10
所以考虑N的后两位即可。
3. 为了简化运算,还可以进一步分析:
不妨算一算(1^1+……+10^10)%10=7,所以(11^11+……+20^20)%10=7(上面得出的4-7+10=7),所以每十个数的和模10余7,
那么我们算出S(1)~S(10)的个位及[S(11)-S(10)]~[S(20)-S(10)]的个位a[i]后,
记b=N%100,则ans=(b/10*7+a[b%20])%10

1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #define repu(i,a,b) for(int i=a;i<b;i++) 5 using namespace std; 6 const int INF = 1000000000; 7 const double eps = 1e-8; 8 const int maxn = 300; 9 10 int cmp[10][4] = 11 { 12 {0,0,0,0}, 13 {1,1,1,1}, 14 {2,4,8,6}, 15 {3,9,7,1}, 16 {4,6,4,6}, 17 {5,5,5,5}, 18 {6,6,6,6}, 19 {7,9,3,1}, 20 {8,4,2,6}, 21 {9,1,9,1} 22 }; 23 char s[maxn]; 24 int main() 25 { 26 while(scanf("%s",s)==1) 27 { 28 if(s[0] == '0') 29 break; 30 31 int ans = 0; 32 int len = strlen(s); 33 int a = s[len-1] - '0'; 34 int b; 35 if(len>=2) 36 b = s[len-2] - '0'; 37 else 38 b = 0; 39 int temp = b*10 + a;///倒数两位 40 ans = (b*7)%10; 41 repu(i,1,a+1) 42 { 43 int k = i + temp - a; 44 ans += cmp[i][(k-1)%4];///加上i的(k-1)%4次方 45 } 46 cout<<ans%10<<endl; 47 } 48 return 0; 49 }