题目描述
小赛是一名聪明的程序员。
他的聪明确保他一定会应聘成功^_^~
在应聘会上,人事主管向小赛提出了这样一个问题——
这次招聘的规则是这样的。
一共有n个人(n>1)参加应聘。
人事主管事先选好了一个正整数x,他会把自己选的这个数x告诉前来应聘的每一个人。
每个人(包括小赛)都可以选择1~m中的任意一个实数(就不要问实数是怎么选的啦!)。参加应聘的人都不会知道其他人选择了什么。
最后所有人都选完数后,我们会把所有数加起来,然后求个平均数(即除以(n+1)),再乘上p/q,设得到的结果为y(y也是个实数).
所有选择的数最接近y的应聘者会被企业选中。
这n个应聘者都同样足够聪明,这n个应聘者都知道其他人也足够聪明,这n个应聘者都想被企业选中。
请你告诉我们,小赛在这种情况下,需要选择1~m中的哪个数才会被企业选中呢?
输入
第一行三个正整数n,m,x,其中n表示参加应聘的人数,m表示应聘者选择数的范围是1~m,x表示人事主管选择的数x.
第二行两个正整数p,q,表示算出的平均数要乘上p/q.
数据保证——p<=q
数据保证——题目有解且有唯一解。
数据保证——
对于30%的测试点,
2<=n<=5,
1<=m,x<=5,
1<=p<=q<=5
对于70%的测试点,
2<=n<=100,
1<=m,x<=100,
1<=p<=q<=100
对于100%的测试点,
2<=n<=10000,
1<=m,x<=10000,
1<=p<=q<=10000
输出
输出一行,包含一个1~m范围内的实数,表示小赛应当选择的数。(四舍五入保留2位小数)
样例输入
2 4 9
2 3
样例输出
3.60
题目来源:博弈问题
C代码如下:
#include<stdio.h>
int main()
{
int n,m,x;
int p,q;
double res = 0.0;
scanf("%d %d %d",&n,&m,&x);
scanf("%d %d",&p,&q);
res = (double)x*p/((n+1)*q-n*p);//假设小赛选的数等于y,根据测试用例可反向推出该式子,见下式(7)
//另外,小赛选择的数必须位于[1,m]之间
if(res < 1.0)
res = 1.0;
if(res > m)
res = m;
printf("%.2f",res);
return 0;
}
我的思路
根据测试用例,假设小赛选择的数等于y(3.6),n=2,m=4,x=9,p=2,q=3,(n+1)个数的和为T,均值为t,则根据题意可得到:
tpq=y⋯⋯⋯式(1)
和
带入测试用例数据得到:
t23=3.6⇒t=5.4⋯式(3)
和
进而可反向推出:
T=9+2∗3.6=x+n∗y⇒t=Tn+1=x+n∗yn+1⋯⋯式(5)
⇒
y=t23=tpq=x+n∗yn+1pq⋯⋯⋯⋯⋯⋯式(6)
根据式(6)可得出:
y=xp(n+1)q−np⋯⋯⋯⋯⋯⋯⋯⋯⋯式(7)