版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lifelikes/article/details/82596672
题意:给出一种游戏的规则,balabalabala,要你求出最后结果的期望。
解题思路:
由于是一个九宫格 所有情况也只有9*9 直接枚举也不会超时。
题目中有*和#号两种位置方格,对于我们来说都是未知的,但对于游戏选手来说只有#是未知的,所以要分开来考虑。
也就是说,题目要求的期望,其实是期望的期望。。。
知道这点后,就可以暴力去枚举了。
复杂度O(能过)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
using namespace std;
const int MOD = 1e9+7;
char str[5][5];
int maps[5][5];
vector<int> res;
int vis[10];
int val[40];
double ans;
int cntans[8];
void init() {
val[6]=10000;
val[7]=36;
val[8]=720;
val[9]=360;
val[10]=80;
val[11]=252;
val[12]=108;
val[13]=72;
val[14]=54;
val[15]=180;
val[16]=72;
val[17]=180;
val[18]=119;
val[19]=36;
val[20]=360;
val[21]=1080;
val[22]=144;
val[23]=1800;
val[24]=3600;
ans=0;
}
int dir[8][3]= {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}};
map<int,bool> M;
int getmax() {
int ans=0;
for(int i=0; i<8; i++) {
int cnt =0;
for(int j=0; j<3; j++) {
int x = dir[i][j]/3,y=dir[i][j]%3;
cnt+=maps[x][y];
}
ans=max(ans,(int)val[cnt]);
}
return ans;
}
void check(int numa,int numb) {
int cnt=0;
for(int i=0; i<numa; i++) {
cnt = cnt*10+res[i];
}
if(M[cnt]==true) {
return;
} else {
M[cnt]=1;
}
int now = 0;
int num = 0;
for(int i=0; i<3; i++) {
for(int j=0; j<3; j++) {
if(str[i][j]=='*') {
maps[i][j]=res[now];
now++;
} else if(str[i][j]!='#') {
maps[i][j]=str[i][j]-'0';
}
}
}
vector<int> V;
for(int i=0; i<numb; i++) {
V.push_back(res[i+numa]);
}
sort(V.begin(),V.end());
for(int i=0; i<8; i++) {
cntans[i]=0;
}
do {
now = 0;
for(int i=0; i<3; i++) {
for(int j=0; j<3; j++) {
if(str[i][j]=='#') {
maps[i][j]=V[now];
now++;
}
}
}
//double maxs = getmax();
for(int i=0; i<8; i++) {
int cnt =0;
for(int j=0; j<3; j++) {
int x = dir[i][j]/3,y=dir[i][j]%3;
cnt+=maps[x][y];
}
cntans[i]+=val[cnt];
}
} while(next_permutation(V.begin(),V.end()));
double maxs=0;
for(int i=0; i<8; i++) {
maxs = max(maxs,1.0*cntans[i]);
}
for(int i=1; i<=numb; i++) {
maxs/=i;
}
ans+=maxs;
//cout<<ans<<endl;
}
long long comb(int m,int n) {
if(n==0) return 1;
if(n==1) return m;
if(n>m/2) return comb(m,m-n);
if(n>1) return (comb(m-1,n-1)+comb(m-1,n));
}
int main() {
int T;
cin>>T;
while(T--) {
for(int i=0; i<3; i++) {
scanf("%s",str[i]);
}
init();
int numa=0,numb=0;
memset(vis,0,sizeof vis);
M.clear();
res.clear();
for(int i=0; i<3; i++) {
for(int j=0; j<3; j++) {
if(str[i][j]!='#' && str[i][j]!='*') {
vis[str[i][j]-'0']=1;
}
numa+=str[i][j]=='*';
numb+=str[i][j]=='#';
}
}
for(int i=1; i<=9; i++) {
if(!vis[i]) {
res.push_back(i);
}
}
sort(res.begin(),res.end());
do {
check(numa,numb);
} while(next_permutation(res.begin(),res.end()));
for(int i=1; i<=numa; i++) {
ans/=i;
}
printf("%.6f\n",ans/comb(numa+numb,numa));
}
return 0;
}