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;
}

 

posted @ 2011-11-18 15:38  wutaoKeen  阅读(293)  评论(0编辑  收藏  举报