double A[110][110], x[110]; voidGauss(int ne, int nv) { int i, j; for (int ce = 0, cv = 0; cv < ne && cv < nv; ++ce, ++cv) { int te = ce; for (i = ce; i < ne; ++i) if (fabs(A[i][cv]) > fabs(A[te][cv])) te = i; if (te != ce) { for (j = cv; j <= nv; ++j) swap(A[ce][j], A[te][j]); } double bas = A[ce][cv]; for (j = cv; j <= nv; ++j) A[ce][j] /= bas; for (i = ce + 1; i < ne; ++i) { for (int j = cv + 1; j <= nv; ++j) A[i][j] -= A[i][cv] * A[ce][j]; } } for (i = ne - 1; i >= 0; --i) { x[i] = A[i][nv]; for (j = i + 1; j < nv; ++j) x[i] -= x[j] * A[i][j]; x[i] /= A[i][i]; } } structAC{ int tr[N][26], tot; int e[N], fail[N]; voidinit(){ for (int i = 0; i <= tot; i++) { e[i] = fail[i] = 0; for (int j = 1; j <= 6; j++)tr[i][j] = 0; } tot = 0; } voidinsert(int *s, int n, int id){ int u = 0; for (int i = 1; i <= n; i++) { if (!tr[u][s[i]]) tr[u][s[i]] = ++tot; u = tr[u][s[i]]; } e[u] = id; } queue<int> q; voidbuild(){ for (int i = 0; i < 26; i++) if (tr[0][i]) q.push(tr[0][i]); while (q.size()) { int u = q.front(); q.pop(); for (int i = 0; i < 26; i++) { if (tr[u][i]) { fail[tr[u][i]] = tr[fail[u]][i], q.push(tr[u][i]); } else tr[u][i] = tr[fail[u]][i]; } } } }ac; int T; int n, m; int t[N]; double ans[N]; intmain(){ scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { scanf("%d", &t[j]); } ac.insert(t, m, i); } ac.build(); memset(A, 0, sizeof(A)); A[0][ac.tot + 1] = -1; for (int i = 0; i <= ac.tot; i++) { A[i][i] = -1; if (ac.e[i])continue; for (int j = 1; j <= 6; j++) { A[ac.tr[i][j]][i] += 1.0 / 6.0; } } Gauss(ac.tot + 1, ac.tot + 1); for (int i = 1; i <= ac.tot; i++) { if (ac.e[i])ans[ac.e[i]] = x[i]; } for (int i = 1; i <= n; i++)printf("%.6lf%c", ans[i], " \n"[i == n]); ac.init(); } return0; }
G - Do not pour out
题意:给定一个底面半径为 1,高为 2 的圆柱体水杯,其中有高为 d 的水,问倾斜到将要溢出时,水平水面的面积。