poj 2645-Boastin' Red Socks-算组合

题意:给你p和q,表示从一个黑箱中一次取两只袜子,两只都是红袜子的概率是p/q。。问你箱子里要多少红袜子和黑袜子?

解析:

首先明确p/q是怎么来的。我们假设总的袜子数量是i,红袜子的数量是j,

p/q就是C(j,2)/C(i,2);即 j(j-1)/(i*(i-1))=p/q;

此时枚举i,来计算j的值。。

注意:若i*(i-1)=tmp,要求出i的话:就是i=(int)sqrt(tmp+0.5)+1;

详见代码解析:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring> 
#include<cmath>
#include<queue>
using namespace std;
#define sf scanf
#define pf printf
#define INF 1<<29
#define eps 1e-6
const double PI=acos(-1.0);
#define lint __int64
#define LL long long 
#define ULLint unsigned long long //2^64-1>1.8*10^19
#define clr(x) memset(x,0,sizeof(x))
#define Clr(x) memset(x,-1,sizeof(x))
LL gcd(LL a , LL b){ 
	return b==0 ? a : gcd(b,a%b);
}
int main(){
	LL p,q;
	while(sf("%lld%lld",&p,&q)){
		if(!p && !q) break;
		if(p==q){
			pf("2 0\n"); 
			continue;
		}
		if(p==0){ 
			printf("0 2\n"); 
			continue;
		}
		LL g=gcd(p,q);
		p/=g; q/=g;
		LL i,j;
		for(i=2; i<=50000; i++)
			if(i*(i-1)%q==0){
				LL n=i*(i-1)/q;
				LL m=n*p;
				j=(LL)sqrt(m+0.5)+1;
				if(j*(j-1)==m && j>=2)
					break;
			}
			if(i>50000)
				pf("impossible\n");
			else        
				pf("%lld %lld\n",j,i-j);
	}
	return 0;
}


你可能感兴趣的:(poj 2645-Boastin' Red Socks-算组合)