(AC自动机+高斯消元)
注:期望逆着推,概率顺着推
#include"queue"
#include"cmath"
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MX = 121;
int a[21][21];
char s[21];
typedef double Matrix[MX][MX];
Matrix A;
void gauss(Matrix A, int n) {
int i, j, k, r;
for(i = 0; i < n; i++) {
r = i;
for(int j = i + 1; j < n; j++) {
if(fabs(A[j][i]) > fabs(A[r][i])) r = j;
}
if(r != i) for(j = 0; j <= n; j++) swap(A[r][j], A[i][j]);
for(int k = i+1; k <= n; k++) A[i][k] /= A[i][i];
A[i][i] = 1;
for(k = i+1; k < n; k++)
if(k!=i){
double f = A[k][i] / A[i][i];
for(j = i; j <= n; j++) A[k][j] -= f * A[i][j];
}
}
for(int i = n-1; i >=0; i--){
for(int j = i-1; j >= 0; j--){
double f = A[j][i]/A[i][i];
A[j][i] -= f*A[i][i];
A[j][n] -= f*A[i][n];
}
}
}
struct AC_machine {
int rear, root;
int Next[MX][6], Fail[MX], End[MX], id[11];
void Init() {
rear = 0;
root = New();
}
int New() {
End[rear] = 0;
for(int i = 0; i < 6; i++) {
Next[rear][i] = -1;
}
return rear++;
}
void Add(char *A, int I) {
int n = strlen(A), now = root;
for(int i = 0; i < n; i++) {
int id = A[i] - '1';
if(Next[now][id] == -1) {
Next[now][id] = New();
}
now = Next[now][id];
}
End[now] = 1;
id[I] = now;
}
void Build() {
queue<int> Q;
Fail[root] = root;
for(int i = 0; i < 6; i++) {
if(Next[root][i] == -1) {
Next[root][i] = root;
} else {
Fail[Next[root][i]] = root;
Q.push(Next[root][i]);
}
}
while(!Q.empty()) {
int u = Q.front(); Q.pop();
if(End[Fail[u]]) End[u] = 1;
for(int i = 0; i < 6; i++) {
if(Next[u][i] == -1) {
Next[u][i] = Next[Fail[u]][i];
} else {
Fail[Next[u][i]] = Next[Fail[u]][i];
Q.push(Next[u][i]);
}
}
}
}
void matrix(Matrix A) {
for(int i = 0; i <= rear; i++)
for(int j = 0; j <= rear; j++)
A[i][j] = 0;
for(int i = 0; i < rear; i++){
if(!End[i]){
for(int j =0 ; j < 6; j++){
int v = Next[i][j];
A[v][i] += 1.0/6.0;
}
}
A[i][i] += -1;
}
A[0][rear] = -1;
}
void out()
{
for(int i = 0; i < rear; i++){
for(int j = 0; j <= rear; j++)
printf("%.6lf ",A[i][j]);
printf("\n");
}
printf("\n\n");
}
void print(int n)
{
for(int i = 1; i <= n; i++){
if(i > 1) printf(" ");
printf("%.6lf",A[id[i]][rear]);
}
printf("\n");
}
} AC;
int main()
{
int T,n,m;
scanf("%d",&T);
while(T--){
AC.Init();
scanf("%d%d",&n,&m);
memset(s,0,sizeof(s));
for(int i = 1; i <= n; i++){
for(int j = 1; j<= m; j++){
scanf("%d",&a[i][j]);
s[j-1] = a[i][j]+'0';
}
AC.Add(s,i);
}
AC.Build();
AC.matrix(A);
gauss(A,AC.rear);
AC.print(n);
}
return 0;
}