解析:  对我来说very hard,用了两个精心制作的函数,用了精心设计的优化算法。看了代码就明白了。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #define N 200
  4 static void fun(int a,int b);        /*求a的b次方,结果保存到s1*/
  5 static void digit_multiply(int a, int p);      
  6 static void large_multiply(int s2); /*求大数积*/
  7 static void large_add(void);        /*求大数和*/
  8 static char s1[N];          
  9 static char t[N], tmp[N];           /*存储中间结果的字符串*/
 10 static char s[N], end[N];           /*最终的结果*/
 11 static int l;                       /*每次都要相乘的字符串s1的长度*/
 12 static char *p1, *p2;
 13 
 14 int main()
 15 {
 16     int a, n, i;
 17     while(scanf("%d %d", &n, &a) == 2){
 18         for(i = 0; i < N; i++)
 19             end[i] = '0';
 20         end[N-1] = '\0';
 21         p1 = &end[N-2];
 22         strcpy(tmp,"1");
 23         for(i = 1; i <= n; i++){
 24             strcpy(s1,tmp);            /*直接获取上一次自乘的s1*/
 25             large_multiply(a);      /*s1与a相乘,结果保留到s1*/
 26             strcpy(tmp,s1);            
 27             large_multiply(i);        /*s1与i相乘,结果保留到s1*/
 28             p2 = s1;
 29             large_add();            /*s1与end相乘,结果保留到end*/
 30         }
 31         printf("%s\n", p1);
 32     }
 33     return 0;
 34 }
 35 static void fun(int a,int b)
 36 {
 37     while(b--)    /*重复b次计算*/
 38         large_multiply(a);
 39 }
 40 /*将s1与s2相乘,并将结果储存到s1中*/
 41 static void large_multiply(int s2) 
 42 {
 43     int i, t;
 44     char *p;
 45     for(i = 0; i < N; i++)   /*s要进行累加中间字符串t,所以要先制空*/
 46         s[i] = '0';
 47     s[N-1] = '\0';
 48     l = strlen(s1) - 1;
 49     i = 0;
 50     while(s2 > 0){
 51         t = s2 % 10;         /*s2的末位数字*/
 52         s2 /= 10;
 53         i++;
 54         digit_multiply(t,i);
 55     }
 56     for(i = 0; i < N; i++)
 57         if(s[i] != '0'){
 58             p = &s[i];
 59             break;
 60         }
 61     strcpy(s1,p);
 62 }
 63 static void digit_multiply(int a, int p)
 64 {
 65     int i, j, temp;
 66     for(i = 0; i < N; i++)    
 67         t[i] = '0';
 68     t[N-1] = '\0';
 69     for(i = l, j = N - 1 - p; i >= 0; i--){
 70         temp = (s1[i] - '0') * a;
 71         t[j] += temp % 10;
 72         t[j-1] += temp / 10;
 73         if(t[j] > '9'){
 74             temp = t[j] - '0';
 75             t[j] = temp % 10 + '0';
 76             t[j-1] += temp / 10;
 77         }
 78         j--;
 79     }
 80     for(i = N - 2; i >= 0; i--){
 81         s[i] += t[i] - '0';
 82         if(s[i] > '9'){
 83             s[i] -= 10;
 84             s[i-1]++;
 85         }
 86     }
 87 }
 88 static void large_add(void)
 89 {
 90     /*默认p1与p2均指向要相加的正确的位置*/
 91     int i, t;
 92     int l1 = strlen(p1) - 1;
 93     int l2 = strlen(p2) - 1;
 94     t = l2 - l1;            
 95     char *p = (l1 >= l2) ? (p1 - 1) : (p1 - 1 - t);
 96     t = p1 - p;             
 97     for(i = 0; i < t; i++)
 98         p[i] = '0';
 99     l1 = strlen(p) - 1;  
100     t = l1 - l2;         
101     for(i = l1; i - t >= 0; i--)
102         p[i] += p2[i - t] - '0';
103     /*相加与进位要分割开来*/
104     for(i = l1; i > 0; i--){
105         if(p[i] > '9'){
106             p[i] -= 10;
107             p[i-1]++;
108         }
109     }
110     if(*p == '0')
111         p++;
112     p1 = p;
113 }