poj 3406 Last digit

该题WA了上午,呜呜.......最后,幸亏lvsi的提醒,把getsum函数改为long long 型就过了,该题与poj 2992 Divisors是同一类型这里我们就不累叙了,这里要注意的就是2与5的对数,我们就把2与5成对处理掉,因为2*5=10,我们就可以忽略2与5成对的情况;

 1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<math.h>
4 #include<string.h>
5 int hash[500024]={0};
6 int prime[100000];
7 int Prime( )
8 {
9 int count=0;
10 int t=(int )sqrt( 1000024 )+1;
11 for( int i=3;i<=t; i+=2 )
12 {
13 if( hash[i/2] )
14 continue;
15 int x=i<<1;
16 for( int j=i*i;j<=1000010;j+=x )
17 hash[j>>1]=1;
18 }
19 prime[++count]=2;
20 for( int i=1; i<500005; i++ )
21 {
22 if( hash[i]==0 )
23 {
24 prime[++count]=( i<<1 )+1;
25 // printf( "%d\n",prime[count] );
26 // getchar();
27 }
28 }
29 return count;
30 }
31 int getsum( long long n,long long p )//一定要用long long型不然就越界了
32 {
33 int sum=0;
34 long long t=p;
35 while( t <= n )
36 {
37 sum += n/t;
38 t *= p;
39 }
40 return sum;
41 }
42
43 int main( )
44 {
45 int n,m;
46 int count=Prime( );
47 // printf( "%d\n",prime[count] );
48 while( scanf( "%d%d",&n,&m )!=EOF )
49 {
50 int sum[3][100000]={0};
51 memset( sum,0,sizeof( sum ) );
52 for( int i=1;prime[i]<=n;i++ )
53 sum[0][i]=getsum( n,prime[i] );
54 for( int i=1;prime[i]<=n-m;i++ )
55 sum[1][i]=getsum( n-m,prime[i] );
56 for( int i=1;prime[i]<=m;i++ )
57 sum[2][i]=getsum( m,prime[i] );
58 for( int i=1;prime[i]<=n;i++ )
59 sum[0][i] -= ( sum[1][i] + sum[2][i] );
60 if( sum[0][1]>sum[0][3] )//成对消除2与5
61 {
62 sum[0][1] -= sum[0][3];
63 sum[0][3]=0;
64 }
65 else
66 {
67 sum[0][3] -= sum[0][1];
68 sum[0][1]=0;
69 }
70 int end=1;
71 for( int i=1;prime[i]<=n;i++ )
72 {
73 if( sum[0][i]!=0 )
74 {
75 for( int j=0;j<sum[0][i];j++ )
76 {
77 end*=prime[i];
78 end%=10;
79 }
80 }
81 }
82 printf( "%d\n",end );
83 }
84 return 0;
85 }


方法二:与POJhttp://poj.org/problem?id=1150是一样的:

注意:看过别人的题解说 因为(m!*(n-m)!)不是n!的一个子集,所以这个不能利用1150的方法。(其实是可以的,只要改一下 num3 与 num9 就行了)如 C(10 ,3)=10!/(3!*7!) 10!=2^8*3^2*5^2*7*9   (3!*7!) = 2^5*3^3*5*7  10! 的 因子3 比(3!*7!) 少,所以把9拆成3即可,其他的因子一定不会比(3!*7!) 少;

View Code
#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<algorithm>

#include<cmath>

#include<queue>

#include<set>

#include<map>

#include<cstring>

#include<vector>

#include<string>

#define LL long long

using namespace std;

int Get_num2( int n ){

    if( n == 0 ) return 0;

    return n/2 + Get_num2( n/2 ); 

}

int Get_num5( int n ){

    if( n == 0 ) return 0;

    return n/5 + Get_num5( n /5 );

    }

int Get_odd( int n , int x ){

    if( n == 0 ) return 0;

    return n/10 + ( n%10 >=x ) + Get_odd( n /5 , x );

}

int Get_numx( int n , int x ){

    if( n == 0 ) return 0;

    return Get_numx( n/2 , x ) + Get_odd( n , x );

    }

int Pow( int n , int num ){

    int sum = 1;

    for( int i= 0 ; i < n ; i ++ )

         sum *= num;

    return sum;

    }

int main(  )

{

    int n,m,num2,num5,num3,num7,num9;

    while( scanf( "%d %d",&n,&m )==2 ){

        num2=Get_num2( n )-Get_num2( n-m )-Get_num2( m );

        num5=Get_num5( n )-Get_num5( n-m )-Get_num5( m );

        if( num5 > num2 ) puts( "5" );

        else{

            num3=Get_numx(n,3)-Get_numx(n-m,3)-Get_numx(m,3);

            num7=(Get_numx(n,7)-Get_numx(n-m,7)-Get_numx(m,7))%4;

            num9=Get_numx(n,9)-Get_numx(n-m,9)-Get_numx(m,9);

            num3 = ( num3 + num9*2 )%4;

            num2 -= num5;

            if( num2 > 0 ){

                num2 %= 4;

                if( num2 == 0 ) num2 = 4;

                }        

            int t = Pow(num2 ,2)*Pow(num3 , 3)*Pow(num7,7);

            printf( "%d\n",t%10 );

        }

    }

    //system( "pause" );

    return 0;

}

 

你可能感兴趣的:(git)