-
2 10 20
Sample Output
-
Case 1: 77.296707046573422 Case 2: 1476.186702884801103
Description
在 牧场物语 游戏中,如果第一次进入游戏就是春1日,开电视按左键就有和女神猜数字的游戏。
如果第二年春1日要玩猜拳游戏,要第一年冬30日参加过除夕大会。
地点:自家住宅
时间:每年的春之月,一到五日(新年特别节目)
游戏角色:女神
可玩次数:5次
注意手上别拿任何物品,否则无法拿取奖品。
打开电视(4个方向有不同的节目),这时候会出现由女神主持的猜数字大小节目,只要按左键频道就可换至此节目。
玩法很简单,女神说一个数字,你猜下一个数字比这个数字大还是小,数字为0-9这几个数。如果相同,继续猜,猜中的次数决定你的奖品,奖品答完后奖品直接到手上。
奖品:
0~1 没东西
2次药草 (各种颜色都有机会得到)
3~9 乔麦粉或年糕 (随机取得)
10~14 轻松茶茶叶
15~19 防晒霜
20~25 润肤霜
26~29 面膜
30~39 香水
40~49 礼物 (保装好的裙子)
50~59 黄金资材 (买价10万G,但不能卖出)
60~69 古代鱼化石 (可卖5000G)
70~79 海盗的宝藏 (可卖10000G)
80~89 料理瓶子 (番茄酱的制作方法)
90~99 料理石板 (考地瓜的制作方法)
100~oo 女神猜拳证书
比如说,一开始女神说数字5,你第一次猜"大",然后女神说数字8,8 > 5, 你说对了一次;
然后,第二次你猜"小",然后女神说数字4, 4 < 8, 你说对了第二次;
然后,第三次你猜"大",然后女神说数字4,4 = 4,女神要你重新说;
然后,第四次你猜"大",然后女神说数字7,7 > 4, 你说对了第三次;
然后,第五次你猜"小",然后女神说数字9,9 > 7, 你猜错了。
于是你总共说对了3次,获得荞麦粉.
你可以假设,每次出现0-9的概率是相同的,都为10%
由于GG不屑与使用金手指等即时存档工具(但是他会在猜数字开始前,存一个档,如果猜数字游戏的结果不理想,他会执着的反复读档重来),所以他想知道的是,假设他十分理智,请问他期望猜多少次,才能在一次游戏中,猜对≥ expect次。
注意:
这里认为的猜一次,是一次选择大小的过程,也就是说,一局游戏中,会猜很多次。而偏执的GG会反复的玩很多局游戏,直到达到目的。
这里认为,GG的足够理智体现在:
如果在一局游戏中,还没有猜正确够expect次,则他会如果上一个数字 ≥ 5,则猜小;如果上一个数字 ≤ 4,则猜大
如果在一局游戏中,他已经猜正确够expect次,则他会如果上一个数字 ≥ 5,则猜大;如果上一个数字 ≤ 4,则猜小,因为已经达到目的后,他希望这局游戏快点结束。
Input
输入首先是一个整数T ( 1 ≤ T ≤ 100 ), 表示测试数据组数
每组测试数据占一行,为一个整数expect,表示GG要在一局游戏中至少猜对expect次。
Output
如果你的答案,和正确答案的差的绝对值≤ 1,则被认为是正确的。具体格式详见样例。
Test Data
大数据:1 ≤ expect ≤ 30
小数据:1 ≤ expect ≤ 100
Hint
看起来游戏没有想象得那么困难,要想猜对10次,获得轻松茶茶叶,期望次数不是1024次,而是77.3次。当然您非要拿到证书的话,就自求多福了。。。
对于大数据,请务必小心精度问题!
今天编程之美挑战赛上CLJ完虐PKU的吴铮锴等人,满分100分拿到了80分,最神奇的是他居然在比赛最后9min怒虐第3题,而且还是一遍AC,牛翻了。更有意思的是他在写第二题的时候,在程序最后几行加上了一个笑脸的注释,眼神直飘右边的网友评论栏,真是大神回眸一笑百媚生啊。。。
下面就是CLJ大神牛气哄哄的代码(虽然只过了小数据),抢在他开始虐第3题前一刻copy来的
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<iostream>
#include<cmath>
#define REP(i,n) for(int i=0;i<n;++i)
using namespace std;
const int MAX_N=100+10;
const int MAX_L=1000+10;
int id[MAX_N][10];
long double equ[MAX_L][MAX_L],b[MAX_L];
void gauss(long double ans[],int n){
int at[1001]={};
memset(at,-1,sizeof at);
bool used[1001]={};//for row
REP(iter,n){
int r,who=-1;
REP(rr,n)if(!used[rr])REP(c,n)
if(at[c]==-1 &&
(who==-1||fabs(equ[rr][c])>fabs(equ[r][who])))
r=rr,who=c;
used[r]=true;
long double by=equ[r][who];
REP(c,n)
equ[r][c]/=by; b[r]/=by;
REP(nr,n) if(r!=nr) {
long double by=equ[nr][who];
REP(c,n) equ[nr][c]-=equ[r][c]*by;
b[nr] -= b[r]*by;
}
at[who]=r;
}
REP(i,n)
ans[i]=b[at[i]];
}
typedef long double ld;
struct Pair{
ld a,b; //a+b*x[rt]
Pair(ld a=0,ld b=0):a(a),b(b){}
Pair operator+(const Pair&o)const{return Pair(a+o.a,b+o.b);}
Pair operator-(const Pair&o)const{return Pair(a-o.a,b-o.b);}
Pair operator*(ld o)const{return Pair(a*o,b*o);}
};
long double solve(int n){
int nid=0;
memset(equ,0,sizeof equ);
memset(b,0,sizeof b);
long double end[10];
REP(i,10){
equ[i][i]-=1;
b[i]=-1;
REP(j,10) {
bool ok=false;
if(i<=4&&j>i)
ok=true;
if(i>=5&&j<i)
ok=true;
if(ok)
continue;
equ[i][j]+=0.1;
}
}
gauss(end,10);
memset(equ,0,sizeof equ);
memset(b,0,sizeof b);
nid=0;
REP(i,n) REP(j,10)
id[i][j]=nid++;
int rt=nid++;
equ[rt][rt]-=1;
REP(j,10){
equ[rt][id[0][j]]+=0.1;
}
REP(i,n) REP(j,10) {
int me=id[i][j];
equ[me][me]-=1;
b[me]=-1;
REP(k,10){
bool ok=false;
if(j<=4 &&k>j) ok=true;
if(j>=5 &&k<j) ok=true;
if(k==j){
equ[me][me]+=0.1;
continue;
}
if(ok) {
if(i+1==n){
b[me]-=0.1*end[k];
continue;
}
int nxt=id[i+1][k];
equ[me][nxt]+=0.1;
} else {
int nxt=rt;
equ[me][nxt]+=0.1;
}
}
}
long double ans[1001];
gauss(ans,nid);
return ans[rt];
}
long double solve2(int n){
int nid=0;
memset(equ,0,sizeof equ);
memset(b,0,sizeof b);
long double end[10];
REP(i,10){
equ[i][i]-=1;
b[i]=-1;
REP(j,10) {
bool ok=false;
if(i<=4&&j>i)
ok=true;
if(i>=5&&j<i)
ok=true;
if(ok)
continue;
equ[i][j]+=0.1;
}
}
gauss(end,10);
Pair what[MAX_L];
nid=0;
REP(i,n) REP(j,10)
id[i][j]=nid++;
int rt=nid++;
for(int i=n-1;i>=0;--i) REP(j,10) {
int me=id[i][j];
Pair ret(1.0,0.0);
REP(k,10){
bool ok=false;
if(j<=4 &&k>j) ok=true;
if(j>=5 &&k<j) ok=true;
if(k==j){
continue;
}
if(ok) {
if(i+1==n){
ret.a+=0.1*end[k];
continue;
}
int nxt=id[i+1][k];
ret=ret+what[nxt]*0.1;
} else {
ret.b+=0.1;
}
}
ret=ret*(1.0/0.9);
what[me] = ret;
}
Pair at;
REP(i,10)
at = at + what[id[0][i]]*0.1;
ld ans = at.a/(1-at.b);
return ans;
}
//19720015116700.7968750000 : long double
//19700972735325.7460937500 :long long double
//19714311348273.06640625000000000000
// >_>
int main(){
int T;cin>>T;
REP(i,T) {
int n;cin>>n;
printf("Case %d: %0.20lf\n",i+1,(double)solve2(n));
}
}