ACM-ICPC 2018 徐州賽區網路預賽 C
阿新 • • 發佈:2018-12-09
題目連結:點選這裡
解題思路:
對於這麼一個3*3的格子一共就是有八種選擇,那麼題目要求在這八種的選擇的的值的期望中輸出最大的那個.
那麼我們首先就去固定'*'號我們不知道而M知道的點,將他變為已知的值,然後再去暴力dfs列舉'#'號的值,求出這次所有‘*’號固定的情況的八種中的最大期望.最後將最大期望和對固定'*'號方案數求均值就是最後最大值期望了.
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mx = 3e5 + 10; int n,m,top,siz[10]; int a[25],num1,num2; double ans1,ans2,ans; bool vis[20]; int b[8][6] = { 0,0,0,1,0,2, 1,0,1,1,1,2, 2,0,2,1,2,2, 0,0,1,0,2,0, 0,1,1,1,2,1, 0,2,1,2,2,2, 0,0,1,1,2,2, 0,2,1,1,2,0}; void init(){ memset(a, 0, sizeof(a)); a[6] = 10000; a[7] = 36; a[8] = 720; a[9] = 360; a[10] = 80; a[11] = 252; a[12] = 108; a[13] = 72; a[14] = 54; a[15] = 180; a[16] = 72; a[17] = 180; a[18] = 119; a[19] = 36; a[20] = 360; a[21] = 1080; a[22] = 144; a[23] = 1800; a[24] = 3600; } char str[10][10]; void dfs2(int *p,int x,int c) { if(c==3){ num2++; ans2 += a[str[p[0]][p[1]]+str[p[2]][p[3]]+str[p[4]][p[5]]-3*'0']; return ; } if(str[p[x]][p[x+1]]=='#') for(int i=1;i<=9;i++){ if(!vis[i]){ vis[i] = 1; str[p[x]][p[x+1]] = i + '0'; dfs2(p,x+2,c+1); vis[i] = 0; str[p[x]][p[x+1]] = '#'; } } else dfs2(p,x+2,c+1); } void dfs1(int x,int y,int c) { if(!c){ num1++,ans1 = 0; for(int i=0;i<8;i++){ ans2 = num2 = 0; dfs2(b[i],0,0); ans1 = max(ans1,ans2/num2); } ans += ans1; return ; } if(str[x][y]=='*') for(int k=1;k<=9;k++){ if(!vis[k]){ str[x][y] = k + '0'; vis[k] = 1; dfs1(y==2?x+1:x,y==2?0:y+1,c-1); vis[k] = 0; str[x][y] = '*'; } } else dfs1(y==2?x+1:x,y==2?0:y+1,c); } int main() { init(); scanf("%d",&n); while(n--) { memset(vis,0,sizeof(vis)); for(int i=0;i<3;i++) scanf("%s",str[i]); int cnt = 0; num1 = num2 = 0; ans = ans1 = ans2 = 0; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ if(str[i][j]=='*') cnt++; else vis[str[i][j]-'0'] = 1; } } dfs1(0,0,cnt); //cout << ans << " " << num1 << endl; printf("%.8lf\n",1.0*ans/num1); } return 0; }