hdu5955Guessing the Dice Roll
阿新 • • 發佈:2019-01-24
#include<map> #include<set> #include<stack> #include<cmath> #include<queue> #include<bitset> #include<math.h> #include<vector> #include<string> #include<stdio.h> #include<cstring> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; typedef double db; typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; const db eps=1e-6; const int N=110; const int M=1e5+10; const ll MOD=1000000007; const int mod=1000000007; const int MAX=1000000010; const double pi=acos(-1.0); int d[N],ans[12]; struct trie { int sz,val[N],fail[N],tr[N][6]; void trie_clear() { sz=0; memset(tr,0,sizeof(tr)); memset(val,0,sizeof(val)); memset(fail,0,sizeof(fail)); } int trie_insert(int *ch) { int w=0; while (*ch!=-1&&tr[w][*ch]) w=tr[w][*ch],ch++; while (*ch!=-1) tr[w][*ch]=++sz,ch++,w=sz; val[w]=1;return w; } void trie_build() { queue<int>Q; for (int i=0;i<6;i++) if (tr[0][i]) Q.push(tr[0][i]); while (!Q.empty()) { int now=Q.front();Q.pop(); if (val[now]) continue ; for (int i=0;i<6;i++) if (tr[now][i]) { fail[tr[now][i]]=tr[fail[now]][i]; Q.push(tr[now][i]); } else tr[now][i]=tr[fail[now]][i]; } } }AC; db p[N][N]; int gauss(int n) { int i,j,k,mxi;db h; for (i=1;i<=n;i++) { mxi=i; for (j=i;j<=n;j++) if (fabs(p[j][i])>fabs(p[mxi][i])) mxi=j; if (fabs(p[mxi][i])<eps) return 0; if (mxi!=i) { for (j=i;j<=n+1;j++) swap(p[i][j],p[mxi][j]); } h=p[i][i]; for (j=i;j<=n+1;j++) p[i][j]/=h; for (j=1;j<=n;j++) if (j!=i) { h=-p[j][i]/p[i][i]; for (k=i;k<=n+1;k++) p[j][k]+=h*p[i][k]; } } return 1; } int main() { int i,j,n,l,T; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &l); AC.trie_clear(); for (i=1;i<=n;i++) { for (j=0;j<l;j++) scanf("%d", &d[j]),d[j]--; d[l]=-1;ans[i]=AC.trie_insert(d); } AC.trie_build(); for (i=0;i<=AC.sz;i++) { d[i]=0; for (j=0;j<6;j++) if (AC.tr[i][j]) d[i]++; } memset(p,0,sizeof(p)); for (i=1;i<=AC.sz;i++) p[i][i]+=1.0; for (i=0;i<6;i++) if (AC.tr[0][i]) p[AC.tr[0][i]][AC.sz+1]+=1.0/d[0]; for (i=1;i<=AC.sz;i++) { for (j=0;j<6;j++) if (AC.tr[i][j]) p[AC.tr[i][j]][i]-=1.0/6.0; if (d[i]!=6&&!AC.val[i]) { for (j=0;j<6;j++) if (AC.tr[0][j]) p[AC.tr[0][j]][i]-=1.0*(6-d[i])/6.0/d[0]; } } gauss(AC.sz); for (i=1;i<n;i++) printf("%.6f ", p[ans[i]][AC.sz+1]); printf("%.6f\n", p[ans[n]][AC.sz+1]); } return 0; }