Guessing the Dice Roll
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 398 Accepted Submission(s): 94
Problem Description
There are N players playing a guessing game. Each player guesses a sequence consists of {1,2,3,4,5,6} with length L, then a dice will be rolled again and again and the roll out sequence will be recorded. The player whose guessing sequence first matches the last L rolls of the dice wins the game.
Input
The first line is the number of test cases. For each test case, the first line contains 2 integers N (1 ≤ N ≤ 10) and L (1 ≤ L ≤ 10). Each of the following N lines contains a guessing sequence with length L. It is guaranteed that the guessing sequences are consist of {1,2,3,4,5,6} and all the guessing sequences are distinct.
Output
For each test case, output a line containing the winning probability of each player with the precision of 6 digits.
Sample Input
3 5 1 1 2 3 4 5 6 2 1 1 2 1 3 1 4 1 5 1 6 1 4 3 1 2 3 2 3 4 3 4 5 4 5 6
Sample Output
0.200000 0.200000 0.200000 0.200000 0.200000 0.027778 0.194444 0.194444 0.194444 0.194444 0.194444 0.285337 0.237781 0.237781 0.239102
Source
Recommend
jiangzijing2015 | We have carefully selected several similar problems for you:
5981
5980
5979
5978
5977
题意:掷骰子,n个人,每人预测一个长度为L的序列,直至筛子序列的最后L个数与某个人预测的一致为止游戏结束(每个人预测的序列不一样,且长度均为L)。
问每个人的获胜概率。
先用ac自动机建立好状态关系,再列方程,用高斯消元求解。
列方程:对于每个点x,假设可以转移到点y,那么dp[y]的胜率要加上dp[x]*p[x->y]
对于根节点要注意,相比于其它结点,概率要额外加1。
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
#define mes(a,x,s) memset(a,x,(s)*sizeof a[0])
#define mem(a,x) memset(a,x,sizeof a)
#define ysk(x) (1<<(x))
typedef long long ll;
typedef pair<int, int> pii;
const int INF =0x3f3f3f3f;
const int maxN= 10,maxL= 10 ,maxNode=101 ;
const double eps=1e-10;
int N,L;
int a[maxN+5][maxL+5];
struct Trie
{
int ch[200][6],val[200],sz;
int pos[maxN+5],f[200],last[200];
void init(){sz=1;mem(ch[0],0);}
void insert( int ind )
{
int x=0;
for1(i,L)
{
int y=a[ind][i];
if(!ch[x][y])
{
mem(ch[sz],0);
val[sz]=0;
ch[x][y]=sz++;
}
x=ch[x][y];
}
val[x]=ind;
pos[ind]=x;
}
void getFail()
{
queue<int>q;
f[0]=0;
for(int c=0;c<6;c++)
{
int y=ch[0][c];
if(y) {f[y]=0;q.push(y);last[y]=0;}
}
while(!q.empty())
{
int x=q.front();q.pop();
for(int c=0;c<6;c++)
{
int y=ch[x][c];
if(!y) {ch[x][c]=ch[f[x]][c];continue; }
q.push(y);
int v=f[x];
while(v&&!ch[v][c]) v=f[v];
f[y]=ch[v][c];
last[y]=val[f[y]]?f[y]:last[f[y]];
}
}
}
}trie;
struct Guass
{
int equ,var;
double a[maxNode+20][maxNode+20],x[maxNode+20];
void init()
{
mem(a,0);
}
void build()
{
int sz=trie.sz;
equ=var=sz;
for0(i,sz)
{
a[i][i]=-1;
}
a[0][var]=-1;
for0(i,sz) if(!trie.val[i])
{
for0(j,6)
{
int y=trie.ch[i][j];
a[y][i]+=1.0/6;
}
}
}
int elimination()
{
int i,j,k,col,max_r;
for(k=0,col=0;k<equ&&col<var;k++,col++)
{
max_r=k;
for(i=k+1;i<equ;i++)
{
if(fabs(a[i][col] )>fabs(a[max_r][col] ) ) max_r=i;
}
if(fabs(a[max_r][col])<eps ) return 0;
if(k!=max_r)
{
for(j=col;j<=var;j++) swap(a[k][j],a[max_r][j] );
}
for(j=col+1;j<=var;j++) a[k][j]/=a[k][col];
a[k][col]=1;
for(i=0;i<equ;i++) if(i!=k)
{
for(j=col+1;j<=var;j++) a[i][j]-=a[k][j]*a[i][col];
a[i][col]=0;
}
}
for(i=0;i<equ;i++) x[i]=a[i][var];
return 1;
}
}guass;
int main()
{
std::ios::sync_with_stdio(false);
int T;cin>>T;
while(T--)
{
cin>>N>>L;
for1(i,N) for1(j,L)
{
cin>>a[i][j];
a[i][j]--;
}
trie.init();
for1(i,N) trie.insert(i);
trie.getFail();
guass.init();
guass.build();
guass.elimination();
for1(i,N)
{
int p=trie.pos[i];
printf("%.6f%c",guass.x[p],i==N?'\n':' ');
}
}
return 0;
}