B: Election
时间限制: 1 Sec 内存限制: 128 MB提交: 122 解决: 21
[ 提交][ 状态][ 讨论版]
题目描述
Reports from the voting stations are starting to trickle in and you hope that you can soon declare a victory.
There are N voters and everyone votes for one of the two candidates (there are no spoiled ballots). In order to win, a candidate needs more than half of the votes. A certain number M≤N of ballots have been counted, and there are Vi votes for candidate i (V1+V2 = M), where V1 is the number of votes your candidate received.
Due to the historical data and results of highly scientific polls, you know that each of the remaining votes has a 50% chance to go to your candidate. That makes you think that you could announce the win before all the votes are counted. So, if the probability of winning strictly exceeds a certain threshold W, the victory is yours! We just hope you are sure of this, we don’t want any scandals...

输入
T lines each contain four integers: N, V1, V2 and W as described above.
The input limits are as follows:
1≤N≤50
50≤W<100
V1,V2≥0
V1 + V2≤N
输出
If the probability that your candidate will win is strictly greater than W%, print
GET A CRATE OF CHAMPAGNE FROM THE BASEMENT!
If your candidate has no chance of winning, print
RECOUNT!
Otherwise, print
PATIENCE, EVERYONE!
样例输入
4
5 0 3 75
5 0 2 75
6 1 0 50
7 4 0 75
样例输出
RECOUNT!
PATIENCE, EVERYONE!
PATIENCE, EVERYONE!
GET A CRATE OF CHAMPAGNE FROM THE BASEMENT!
提示
自问 再也没有比这道题 恶心的题了;
题意 真心 mmp;
题意: 投票选举 有n 现在有 v1 对方有v2 剩下票 每一张 获得的概率为1/2; 获胜 必须 票数 超过 n/2
问你 当前状态下 推算 你获胜的概率是不是 大于w 是 yes 如果 剩下票数全部给你 也不够 n/2 则 no
其余 不超过w 输出possible;
现在有v1 张 剩下 票数为 t1: n-v1-v2; 离获胜n/2 还缺 t2: n/2 -v1+1 考虑到n为奇数的问题 所以+1
从 t1 要至少选择t2 张
C (t1,t2) * 1/2 ^t2 * 1/2 ^ t1-t2 =C(t1,t2) * 1/2^t1 这个意思是 1/2 获胜概率 1/2 失败概率 获胜是 t2 失败 是 t1-t2 所以总是为 t1
Sigma C(t1,t2)---C(t1,t1) * 1/2 ^t1 > w 则 获胜 转换为 Sigma C(t1,t2)---C(t1,t1) > 2^t1 * w
失败 是 v1 + n-v1-v2 <= n/2 化简为 2*v2 >=n
注意 在求组合公式 和 快速幂时 不需要 不需要 不需要 mod 因为 %mod 了 所以 mmp 一直wa
代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define S1(n) scanf("%d",&n)
#define SL1(n) scanf("%I64d",&n)
#define S2(n,m) scanf("%d%d",&n,&m)
#define SL2(n,m) scanf("%I64d%I64d",&n,&m)
#define Pr(n) printf("%d\n",n)
using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};
ll inv[maxn*2],fac[maxn];
ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;}
ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll ans=exgcd(b,a%b,x,y);ll temp=x;x=y;y=temp-a/b*y;return ans;}
ll lcm(ll a,ll b){ return b/gcd(a,b)*a;}
ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x);x=(x*x);}return res;}
void INV(){inv[1] = 1;for(int i = 2; i < maxn; i++) inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){ x=1; y=0; d=a; }else{ ex_gcd(b,a%b,d,y,x); y-=x*(a/b);}}
void Fac(){fac[0]=1;for(int i=1;i<=maxn;i++)fac[i]=(fac[i-1]*i)%MOD;}
ll inv_exgcd(ll a,ll n){ll d,x,y;ex_gcd(a,n,d,x,y);return d==1?(x+n)%n:-1;}
ll inv1(ll b){return b==1?1:(MOD-MOD/b)*inv1(MOD%b)%MOD;}
ll inv2(ll b){return qpow(b,MOD-2);}
ll cal(ll m,ll n){if(m<n)return 0;return (fac[m]*inv[fac[n]]%MOD)%MOD*inv[fac[m-n]]%MOD;}
ll cals(ll m,ll n){if(m<n)return 0;return (fac[m]*inv1(fac[n])%MOD)%MOD*inv1(fac[m-n])%MOD;}
ll C[1005][1005];
void init()
{
C[0][0]=1;
for(int i=1;i<=50;i++)
for(int j=0;j<=i;j++){
C[i][j]=(j==0)?1:(C[i-1][j]+C[i-1][j-1]);
}
}
ll n,v1,v2,w;
int main()
{
init();
int t;
//cout<<C[50][25]<<endl;
cin>>t;
while(t--)
{
scanf("%lld %lld %lld %lld",&n,&v1,&v2,&w);
{
ll temp1=n-v1-v2;//上
ll temp2=n/2+1-v1; //下
if(temp2<=0)temp2=0;
ll sum=0;
int flag=0;
ll q= qpow(2,temp1);
for(int i=temp2;i<=temp1&&!flag;i++)
{
sum+=C[temp1][i];
if(sum*100>w*q)
flag=1;
}
if(flag)
printf("GET A CRATE OF CHAMPAGNE FROM THE BASEMENT!\n");
else if(v2>=ceil(n*1.0/2))
printf("RECOUNT!\n");
else
printf("PATIENCE, EVERYONE!\n");
}
}
return 0;
}
13