本蒟蒻代码如下,无法通过第二个测试样例,敬请各位神犇出手相助。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=100050;
queue<int> Q;
double start[15]={0,0,1.0/36,2.0/36,3.0/36,4.0/36,5.0/36,6.0/36,5.0/36,4.0/36,3.0/36,2.0/36,1.0/36};
double p[MAXN],f[MAXN];
int fly[MAXN],indegree[MAXN];
int n,m;
void bfs()
{
int t;
Q.push(0);
while (Q.size()>0)
{
t=Q.front();
Q.pop();
if (t>=n)
{
continue;
}
if (fly[t]>0)
{
f[fly[t]]+=f[t];
p[fly[t]]+=p[t];
indegree[fly[t]]--;
if (indegree[fly[t]]==0)
{
Q.push(fly[t]);
}
continue;
}
for (int i=2;i<=12;i++)
{
f[t+i]+=(f[t]+1)*p[t]*start[i];
p[t+i]+=p[t]*start[i];
indegree[t+i]--;
if (indegree[t+i]==0)
{
Q.push(t+i);
}
}
}
}
int main()
{
//freopen("dice.in","r",stdin);
//freopen("dice.out","w",stdout);
int u,v;
double ans=0.0;
scanf("%d%d",&n,&m);
indegree[0]=indegree[1]=0;
indegree[2]=1;
for (int i=3;i<=13;i++)
{
indegree[i]=i-2;
}
for (int i=14;i<=n+11;i++)
{
indegree[i]=11;
}
memset(fly,0,sizeof(fly));
for (int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
fly[u]=v;
if (u==v-1||u<v-12)
{
indegree[v]++;
}
}
p[0]=1.0;
f[0]=0.0;
bfs();
for (int i=n;i<=n+11;i++)
{
ans+=f[i];
}
printf("%0.4lf",ans);
return 0;
}
题面:
2016年全国信息学奥林匹克竞赛黑龙江省选拔赛 2. 小明的智力游戏 (dice.pas/c/cpp)
【题目描述】 小明喜欢玩一些智力游戏。假设有一个一维棋盘,在该棋盘上从左至右共有 最初在编号为 个格子,编号从到。小明有一个棋子, 的格子中。他每次掷两 个骰子,每个骰子都有六个面,而且掷到每个面的概率都相同,骰子的点数分别是 1,2,3,4,5,6。 当棋子在编号为 的格子中时,掷到的两个骰子点数分别是 子中。当大于或等于的时候,小明就结束游戏。 和,那么棋子将会移动到编号为的格 小明是一个比较喜欢偷懒的人,他不喜欢掷那么多次骰子,所以在棋盘中有 不用掷骰子直接从编号为 的格子跳到编号为 条飞行线路,对于第 的格子。如果还有另一条飞行线路起点是编号为 那么小明就可以按照这条线路继续向前跳动。保证每个格子只可以作为一条飞行路线的起点。 现在想知道完成这个游戏需要掷骰子的次数期望值是多少。
【输入描述】 输入文件名为 dice.in 。 第一行给出,。 接下来行,每行包括两个整数
【输出描述】 输出文件名为 dice.out 。 ,(<<),表示格子 到格子 有一条飞行线路。 ( 条飞行线路来说,可以 )的格子, 输出文件包含一个整数,即相应输入文件的答案。输出完成这个游戏需要掷骰子的次数期望值是多少,结果保留小数点后4 位。
【输入样例1】 2 0
【输出样例1】 1.0000
【输入样例2】
8 3
2 4
4 5
7 8
【输出样例2】 1.4213