zoukankan      html  css  js  c++  java
  • [HDU5955]Guessing the Dice Roll

    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
     

     
    对所有串建AC自动机,然后按照Trie图建立递推关系,转化成矩阵,用高斯消元解决带环的转移。
    写起来略恶心,反正我是不想调了。
     

     
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <cmath>
    using namespace std;
    #define reg register
    inline int read() {
        int res = 0;char ch=getchar();bool fu=0;
        while(!isdigit(ch))fu|=(ch=='-'),ch=getchar();
        while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return fu?-res:res;
    }
    
    int T;
    int n, L;
    int nxt[105][7], fail[105], danger[105], tot, who[105];
    inline void ins(int *s, int id) 
    {
        int now = 0;
        for (reg int i = 1 ; i <= L ; i ++)
            now = nxt[now][s[i]] ? nxt[now][s[i]] : nxt[now][s[i]] = ++tot;
        danger[now] = 1;
        who[now] = id;
    }
    
    inline void Build()
    {
        queue <int> q;
        for (reg int i = 1 ; i <= 6 ;i ++) if (nxt[0][i]) q.push(nxt[0][i]);
        while(!q.empty())
        {
            int x = q.front();q.pop();
            for (reg int i = 1 ; i <= 6 ; i ++)
                if (nxt[x][i]) fail[nxt[x][i]] = nxt[fail[x]][i], q.push(nxt[x][i]);
                else nxt[x][i] = nxt[fail[x]][i];
            danger[x] |= danger[fail[x]];
        }
    }
    
    long double a[105][105], ans[15];
    
    inline void Gauss()
    {
        for (reg int i = 0 ; i <= tot ; i ++)
        {
            int k = i;
            for (reg int j = i ; j <= tot ; j ++)
                if (fabs(a[j][i]) > fabs(a[k][i])) k = j;
            if (k != i) swap(a[k], a[i]);
            for (reg int j = 0 ; j <= tot ; j ++)
            {
                if (i == j) continue;
                long double r = a[j][i] / a[i][i];
                for (reg int k = i ; k <= tot + 1 ; k ++)
                    a[j][k] -= a[i][k] * r;
            }
        }
    }
    
    int main()
    {
        T = read();
        while(T--)
        {
            memset(nxt, 0, sizeof nxt);
            memset(fail, 0, sizeof fail);
            memset(danger, 0, sizeof danger);
            tot = 0;
            n = read(), L = read();
            int tmp[13];
            for (reg int i = 1 ; i <= n ; i ++)
            {
                for (reg int j = 1 ; j <= L ; j ++) tmp[j] = read();
                ins(tmp, i);
            }
            Build();
            memset(a, 0, sizeof a);
            for (reg int i = 0 ; i <= tot ; i ++)
            {
                a[i][i] -= 1.0;
                if (danger[i]) continue;
                for (reg int j = 1 ; j <= 6 ; j ++)
                    a[nxt[i][j]][i] += 1.0 / 6.0;
            }
            a[0][tot + 1] = -1.0;
    //        for(int i=0;i<=tot;i++,puts(""))
    //            for(int j=0;j<=tot+1;j++) printf("%.2Lf ",a[i][j]);
            Gauss();
            for (reg int i = 0 ; i <= tot ; i ++)
                if (danger[i]) ans[who[i]] = a[i][tot + 1] / a[i][i];
            for (reg int i = 1 ; i < n ; i ++) printf("%.6Lf ", ans[i]);
            printf("%.6Lf
    ", ans[n]);
        }
        return 0;
    }
  • 相关阅读:
    UVa 116 单向TSP(多段图最短路)
    POJ 1328 Radar Installation(贪心)
    POJ 1260 Pearls
    POJ 1836 Alignment
    POJ 3267 The Cow Lexicon
    UVa 1620 懒惰的苏珊(逆序数)
    POJ 1018 Communication System(DP)
    UVa 1347 旅行
    UVa 437 巴比伦塔
    UVa 1025 城市里的间谍
  • 原文地址:https://www.cnblogs.com/BriMon/p/9842122.html
Copyright © 2011-2022 走看看