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!) 少;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }