彩票问题求解(赣州市NOIP2006选拔赛试题)


/*
某地发行一套彩票。彩票上写有1到M这M个自然数。彩民可以在这M个数中任意选取N个不同的数打圈。每个彩民只能买一张彩票,不同的彩民的彩票上的选择不同。
每次抽奖将抽出两个自然数X和Y。如果某人拿到的彩票上,所选N个自然数的倒数和,恰好等于X/Y,则他将获得一个纪念品。
已知抽奖结果X和Y。现在的问题是,必须准备多少纪念品,才能保证支付所有获奖者的奖品。
    输入输出要求
输入文件有且仅有一行,就是用空格分开的四个整数N,M,X,Y。
输出文件有且仅有一行,即所需准备的纪念品数量。
1≤X, Y≤100,1≤N≤10,1≤M≤50。
输入数据保证输出结果不超过105。
   输入输出样例

Money.in    Money.out
2 4 3 4    1
*/

         
#include 
< stdio.h >
#include 
< string .h >
#include 
< math.h >
#include 
< stdlib.h >

#define  MAX 101

 
long  total  =   0  ;
int  m,n,x,y ;
int  flag[MAX]  =  { 0 } ;
int  save[MAX]  =  { 0 } ;
 

int  gcd( int  a, int  b)
{
    
if  ( b  ==   0 )
    
return  a ;
    
else
    
return  gcd(b,a % b) ;
}


int  is_same()
{
    
int  fz = 0 ,fm = 0  ;
    
int  i,j,k,maxk,temp;
    maxk 
=  gcd(save[ 1 ],save[ 2 ]) ;
    fm 
=  (save[ 1 ] * save[ 2 ]) / maxk ;
    fz 
=  save[ 1 ] / maxk  +  save[ 2 ] / maxk ;
    save[
2 =  fm ;
    
for (i = 3 ; i <=  n ; i ++ )
    {
          maxk 
=  gcd(save[i - 1 ],save[i]);
          fm 
=  (save[i - 1 ] * save[i]) / maxk ;
          fz 
=  fz * (save[i - 1 ] / maxk) + save[i] / maxk ;
          save[i] 
=  fm ;
    }
    
    
if (fz  ==  x  &&  fm  ==  y)
    
return   1  ;
    
else
    
return   0  ;
}
    
void  find ( int  num)
{
     
int  i,j ;
     
if  ( num  >  n)
     {
          
          
if (is_same())
          {
         
          total
++  ;
          
          
          }
          test 
++  ;
     }
     
else
     {
         
for (i = 1  ; i <=  m ; i ++ )
         
if  (  ! flag[i]  &&  i  >  save[num - 1 ])
         {
               
              flag[i] 
=   1  ;
              save[num] 
=  i ;
              find (num
+ 1 );
              flag[i] 
=   0  ;
               
              save[num] 
=   0  ;
         }
     }
}          
     
int  main( void )
{
  
    
int  max,h;
    
    scanf(
" %d %d %d %d " , & n, & m, & x, & y);
    
    max 
=  gcd(x,y) ;  /* 检查它是否为最简式 */
     
    
if  ( max  >   1 /* 化为最简式 */
    {   
      x 
/=  max ;
      y 
/=  max ;
    }
    
    
if  ( n  ==   1 /* 如果n为1直接处理 */
    {
         
if  ( x  ==   1 )
         {
          
for (h = 1  ; h <=  m ; h ++ )
          
if  ( y  ==  h)
          total 
++  ;
          }
    }
    
    
else  
    {      
          find (
1 );
    }
    
    printf(
" %ld " ,total);
    
     
    
return   0  ;
}

        
    
 

你可能感兴趣的:(String,math.h)