HDOJ 1066-数学、N!のゼロ以外の端数

2048 ワード

/*
 N!   0   。  2 120       0  。
  N   ,     。
     0     5        。 f(n) n!    0 。
  f(n)=((n%5)!* f(n/5) *2^(n/5))%10
  2       5, 1     5    1 ,  5           5 ,
        1 n/5,   1*2*3*4*5=6*7*8*9*5=11*12*13*14*5=...=2(      0 ),    2^(n/5)。
             
(  n 123,        121,122,123        )。
  : http://hi.baidu.com/nicker2010/item/4fa83c4c5050b3e5a4c066ec     
*/
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

const int Lib[4]={6,2,4,8};  //2^n    2,4,8,6   
const int fact[10]={1,1,2,6,4,2,2,4,2,8};  //10       

char s[200];
int a[200];  //   ,a[0]     

void todigit(char s[],int a[])
{
    a[2]=0;
    a[0]=strlen(s);
    for (int i=0; i<a[0]; i++) a[a[0]-i]=s[i]-'0';
}

void mult(int a[],int x) //     
{  
    int j=0;
    for (int i=a[0]; i>0; i--)
    {
        int k1=(j*10+a[i])/x;
        j=(j*10+a[i])%x;
        a[i]=k1;
    }
    while (a[0]>1 && a[a[0]]==0) a[0]--;
}

int last_nunzero(int a[])
{
    if (a[0]==1) return fact[a[1]];
    int x1=fact[a[1]%5];                //x1=(n%5)!
    mult(a,5);
    int x2=Lib[(a[2]*10+a[1])%4];       //x2=(2^(n/5))%10
    int ret=(x1*x2*last_nunzero(a))%10; //       
    return ret;
}

int main()
{
    while (gets(s))
    {
        todigit(s,a);
        printf("%d
",last_nunzero(a)); } return 0; } /* : ( , ( WA ~),) #include <stdio.h> #include <string.h> #define MAXN 10000 int lastdigit(char* buf){ const int mod[20]={1,1,2,6,4,2,2,4,2,8,4,4,8,4,6,8,8,6,8,2}; int len=strlen(buf),a[MAXN],i,c,ret=1; if (len==1) return mod[buf[0]-'0']; for (i=0;i<len;i++) a[i]=buf[len-1-i]-'0'; for (;len;len-=!a[len-1]){ ret=ret*mod[a[1]%2*10+a[0]]%5; for (c=0,i=len-1;i>=0;i--) c=c*10+a[i],a[i]=c/5,c%=5; } return ret+ret%2*5; } int main() { char en[1000]; while(scanf("%s",en)!=EOF) { int temp = lastdigit(en); printf("%d
",temp); } return 0; } */