HDU-5955-Guessing the Dice Roll
描述
題解
程式碼
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX_LEN = 1010;
const int MAXN = 120;
const int MAXM = 6;
const int MAXF = 15 ;
const double EPS = 1e-6;
const double MAGIC = 1.0 / 6;
int n, L, sz;
int fp[MAXF];
int tag[MAXN];
int fail[MAXN];
int trie[MAXN][MAXM];
queue<int> qi;
/* *********** Aho *********** */
struct Aho
{
int root;
int newnode() // 靜態建立新節點
{
memset(trie[sz], -1 , sizeof(trie[sz]));
tag[sz] = 0;
sz++;
return sz - 1;
}
void init()
{
sz = 0;
newnode();
}
void insert(int s[], int id) // 插入字串構建ac自動機,構建trie樹
{
int len = L, p = 0;
for (int i = 0; i < len; i++)
{
int _id = s[i] - 1;
if (trie[p][_id] == -1)
{
trie[p][_id] = newnode();
}
p = trie[p][_id];
}
tag[p] = id; // 結束標記
fp[id] = p;
}
void getfail() // 構建自動機fail指標
{
while (!qi.empty())
{
qi.pop();
}
fail[root] = root; // root指向root
for (int i = 0; i < MAXM; i++)
{
if (trie[root][i] == -1) // 第一個字元不存在,指向root
{
trie[root][i] = root;
}
else // 第一個字元的fail指標指向root
{
fail[trie[root][i]] = root;
qi.push(trie[root][i]); // 並放入佇列,待bfs擴充套件
}
}
while (!qi.empty())
{
int u = qi.front(); // 取擴充套件節點
qi.pop();
if (tag[fail[u]])
{
tag[u] = tag[fail[u]]; // 如果之前是tag,直接標記
}
for (int i = 0; i < MAXM; i++) // 遍歷所有子節點
{
if (trie[u][i] == -1) // 如果不存在,則子節點直接指向fail[u]節點的對應子節點
{
trie[u][i] = trie[fail[u]][i];
}
else // 如果存在,則該節點的fail指標指向fail[u]節點對應的子節點
{
fail[trie[u][i]] = trie[fail[u]][i];
qi.push(trie[u][i]); // 繼續擴充套件
}
}
}
}
} aho;
/* *********** Guass *********** */
int equ, var;
double x[MAXN];
double a[MAXN][MAXN];
int Gauss()
{
int max_r;
for (int k = 0, col = 0; k < equ && col < var; k++, col++)
{
max_r = k;
for (int 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 (int j = col; j < var; j++)
{
swap(a[k][j], a[max_r][j]);
}
swap(x[k], x[max_r]);
}
x[k] /= a[k][col];
for (int j = col + 1; j < var; j++)
{
a[k][j] /= a[k][col];
}
a[k][col] = 1;
for (int i = 0; i < equ; i++)
{
if (i != k)
{
x[i] -= x[k] * a[i][k];
for (int j = col + 1; j < var; j++)
{
a[i][j] -= a[k][j] * a[i][col];
}
a[i][col] = 0;
}
}
}
return 1;
}
void init_guass(int n, int m)
{
memset(x, 0, sizeof(x));
memset(a, 0, sizeof(a));
var = n;
equ = m;
}
int son[MAXN];
void build() // 建立方程組
{
init_guass(sz, sz);
for (int i = 0; i < sz; i++)
{
if (!tag[i])
{
for (int j = 0; j < MAXM; j++)
{
a[trie[i][j]][i] += MAGIC;
}
}
a[i][i] += -1;
}
x[0] += -1; // 虛擬節點以1的概率轉移到節點0
}
int name[MAXF][MAXF];
int main()
{
int T;
cin >> T;
while (T--)
{
cin >> n >> L;
aho.init();
for (int i = 0; i < n; i++)
{
for (int j = 0; j < L; j++)
{
scanf("%d", name[i] + j);
}
aho.insert(name[i], i + 1);
}
aho.getfail();
build();
Gauss();
for (int i = 1; i <= n; i++)
{
printf("%.6f%c", x[fp[i]], i == n ? '\n' : ' ');
}
}
return 0;
}
相關推薦
HDU-5955-Guessing the Dice Roll
ACM模版 描述 題解 AC 自動機 + 高斯消元。 程式碼 #include <queue> #include <cmath> #include <cstdio> #include <c
hdu 5995 Guessing the Dice Roll(AC自動機+矩陣)
scan hide turn define fabs 自動機 lap none pac 題目鏈接:hdu 5995 Guessing the Dice Roll 題意: 有一個6面的骰子,有n(n≤10)個人每個人猜了一個長度為l(l≤10)的序列,不停的擲骰子直到滿足一個
hdu5955 Guessing the Dice Roll【AC自動機】【高斯消元】【概率】【待補...】
inpu ont recommend match ble 北大 problem ng2 bottom 2016沈陽區域賽http://acm.hdu.edu.cn/showproblem.php?pid=5955 Guessing the Dice Roll Time Li
hdu5955Guessing the Dice Roll
#include<map> #include<set> #include<stack> #include<cmath> #include<queue> #include<bitset> #include<math.h> #in
HDU 4930 Fighting the Landlords(扯淡模擬題)
href blank 。。 clear break 輸出 family fig set Fighting the Landlords 大意: 鬥地主。。。。 分別給出兩把手牌,肯定都合法。每張牌大小順序是Y (i.e. colored Joker) &g
[HDU 4344]Mark the Rope(Pollard_rho+Miller_Rabin)
質因數 pre from == mar des last span his Description Eric has a long rope whose length is N, now he wants to mark on the rope with differen
HDU-1556 Color the ball 【差分數組】
前綴 思想 bsp 前綴和 一個 sizeof all 屬於 pri Problem Description N個氣球排成一排,從左到右依次編號為1,2,3....N.每次給定2個整數a b(a <= b),lele便為騎上他的“小飛鴿"牌電動車從氣球a開始到氣球b
HDU 5366:The mook jong 遞推
hdu ons accep ucc soft cst stream mil overflow The mook jong Accepts: 506 Submissions: 1281 Time Limit: 2000/1000 MS (Java/O
HDU 1133 Buy the Ticket 卡特蘭數
i++ ava () pos str mat bre == ann 設50元的人為+1 100元的人為-1 滿足前隨意k個人的和大於等於0 卡特蘭數 C(n+m, m)-C(n+m, m+1)*n!*m! import java.math.*; import java
HDU 5063 Operation the Sequence(暴力)
tracking pos sun 鏈接 char height ans wrap %d HDU 5063 Operation the Sequence 題目鏈接 把操作存下來。因為僅僅有50個操作,所以每次把操作逆回去執行一遍,就能求出在原來的數列中的位置。輸出就
HDU 4930 Fighting the Landlords(暴力枚舉+模擬)
mil hdu scan cpp ref i++ trac ++ %d HDU 4930 Fighting the Landlords 題目鏈接 題意:就是題中那幾種牌型。假設先手能一步走完。或者一步讓後手無法管上,就贏 思路:先枚舉出兩個人全部可能的牌型的最大
Hdu 1194 Beat the Spread!
org problem nbsp bow absolut amp game com diff Beat the Spread! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja
hdu 6016 Count the Sheep
判斷 題意 cond ans spa air clas int ret BestCoder Round #92 B題 (今天突然想起來這道題在做的時候卡了cin 而且似乎也有爆int的坑 就拿出來記錄一下 ((這道題能用來測試輸入輸出外掛的性能 中文題意不解釋 比賽
hdu 4348 To the moon(主席樹區間操作)
esp ace 標記 return ++i urn div acm str 題目鏈接:hdu 4348 To the moon 題意: 給你n個數,有m個操作。 1.給區間[l,r]的所有數+d,並且時間戳+1 2.詢問當前時間戳的區間和。 3.詢問過去時間戳t的區間和。
HDU 1598 find the most comfortable road
改進 sort using problem clu spa mes span nbsp https://vjudge.net/problem/HDU-1598 思路:一開始想了很久才想通,先把邊進行排序,然後枚舉邊的起點和終點,但是這樣就是三重循環,t了。之後的改進,大概就
HDU Ignatius and the Princess III (母函數)
tex namespace class .net author def urn rst isp Problem Description "Well, it seems the first problem is too easy. I will let you know h
HDU 4869 Turn The Pokers 思維+組合
+= hdu 累加 color bsp 相差 while ... 1的個數 HDU 4869題意:m張牌,朝上狀態為1,朝下狀態為0,現在有n個操作 第i次操作可以反轉任意xi張牌初始牌全部朝下,n,m<=1e5,問n次操作後能得到多少種不同的狀態? 關心的是最後的狀
KMP——hdu 3336 count the string
miss calculate != cnblogs ber lar ota accep can Count the string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (J
hdu 1599 find the mincost route
std word esp func space hid floyd tracking oss pid=1599">click here ~~ ***find the mincost ro
線段樹(求單結點) hdu 1556 Color the ball
inpu int namespace bmi define != tle ring desc Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java