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

来源:互联网 发布:ubuntu 自动休眠 编辑:程序博客网 时间:2024/06/08 18:16

/*
某地发行一套彩票。彩票上写有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 ;
}

        
    
 
原创粉丝点击