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