题意:共有n个袜子,其中红袜子m只,告诉你拿到两只袜子都是红袜子的概率为p/q,问在袜子数最少的情况下,有多少红袜子,多少黑袜子。
思路:m*(m-1) / n*(n-1) =p/q 那么 每次枚举n,可以得到 m*(m-1)= n*(n-1)*p/q,用map存储所有的m可以表示的数量,这样可以快速得到m。
AC代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
map<ll,ll> match;
int main()
{
ll n,m,p,q,ret;
int i,j,k;
bool flag;
for(m=2;m<=50000;m++)
match[m*m-m]=m;
while(~scanf("%lld%lld",&p,&q))
{
if(p==0 && q==0)
break;
if(p==0)
{
printf("0 2\n");
continue;
}
flag=0;
for(n=2;n<=50000;n++)
{
ret=n*(n-1)*p;
if(ret%q==0)
{
ret/=q;
if(match[ret]>0)
{
m=match[ret];
flag=1;
break;
}
}
}
if(flag)
printf("%lld %lld\n",m,n-m);
else
printf("impossible\n");
}
}