ACM-ICPC 2018 徐州赛区网络预赛 C. Cacti Lottery —— 暴力dfs

Morgana is playing a game called cacti lottery. In this game, morgana has a
3×33 \times 3
3×3 grid graph, and the graph is filled with
11
1 ~
99
9 , each number appears only once. The game is interesting, he doesn’t know some numbers, but there are also some numbers he knows but don’t want to tell you.
Now he should choose three grids, these three grids should be in the same column or in the same row or in the diagonal line. Only after this choice, can he know all numbers in the grid graph. Then he sums the three numbers in the grids he chooses, get the reward as follows:
Sum
Reward
6
10000
7
36
8
720
9
360
10
80
11
252
12
108
13
72
14
54
15
180
16
72
17
180
18
119
19
36
20
360
21
1080
22
144
23
1800
24
3600
Then he wants you to predict the expected reward he will get if he is clever enough in the condition that he doesn’t want to tell you something he knows.
(“He is clever enough” means he will choose the max expected reward row or column or dianonal in the condition that he knows some numbers. And you know that he knows some number, but you don’t know what they are exactly. So you should predict his expected reward in your opinion. )
Input
First line contains one integers (T≤100) represents the number of test cases.
Then each cases contains three lines, giving the
3×3 grid graph. ‘*’ means Morgana knows but doesn’t want to tell you, ‘#’ means Morgana doesn’t know, ‘0’ ~ ‘9’ means the public number that Morgana and you both know.
Output
T lines, output the answer. If the answer is
A, and your answer is
B. Your answer will be considered as correct if and only if
∣(A−B)∣<1e−5 .
本题答案不唯一,符合要求的答案均正确
样例输入
复制
2
123
***

12*
45#
78#
样例输出
复制
10000
4313.16666667
刚学算法的时候一遇到题目就在想是什么算法,现在:qnmd算法,暴力和打表才是王道
这道题在比赛的时候没看,一直在做b题,最后用了一种特别麻烦的方法,最后还没敲出来就gg了。
它取的是一行或者一列或者一个对角线,所以期望不是每次都算最大的那个,而是算吧*填满之后8种可能的期望。
第一个dfs填*,第二个填#

#include<bits/stdc++.h>
using namespace std;
#define pa pair<int,int>
#define mp(a,b) make_pair(a,b)
int vis[15];
char Map[5][5];
int sum[10];
int ct1,ct2,cas;
double ans;
int reward[]={0,0,0,0,0,0,10000,36,720,360,80,252,108,72,54,180,72,180,119,36,360,1080,144,1800,3600};
pa p1[10],p2[10];
int a(int n,int m)
{
    int ans=1;
    for(int i=1;i<=m;i++)
        ans*=(n-i+1);
    return ans;
}
void check()
{
    for(int i=1;i<=3;i++)
        sum[i]+=reward[Map[i][1]-'0'+Map[i][2]-'0'+Map[i][3]-'0'];
    for(int i=4;i<=6;i++)
        sum[i]+=reward[Map[1][i-3]-'0'+Map[2][i-3]-'0'+Map[3][i-3]-'0'];
    sum[7]+=reward[Map[1][1]-'0'+Map[2][2]-'0'+Map[3][3]-'0'];
    sum[8]+=reward[Map[3][1]-'0'+Map[2][2]-'0'+Map[1][3]-'0'];
}
void dfs2(int pos)
{
    if(pos>ct2)
    {
        check();
        return ;
    }
    for(int i=1;i<=9;i++)
    {
        if(vis[i])
            continue;
        vis[i]=1;
        Map[p2[pos].first][p2[pos].second]=i+'0';
        dfs2(pos+1);
        vis[i]=0;
    }
}
void dfs(int pos)
{
    if(pos>ct1)
    {
        memset(sum,0,sizeof(sum));
        dfs2(1);
        int maxn=0;
        for(int i=1;i<=8;i++)
            maxn=max(maxn,sum[i]);
        ans+=(double)maxn/a(ct2,ct2);
        return ;
    }
    for(int i=1;i<=9;i++)
    {
        if(vis[i])
            continue;
        vis[i]=1;
        Map[p1[pos].first][p1[pos].second]=i+'0';
        dfs(pos+1);
        vis[i]=0;
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ct1=ct2=cas=0;
        ans=0.0;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=3;i++)
        {
            scanf("%s",Map[i]+1);
            for(int j=1;j<=3;j++)
            {
                if(Map[i][j]=='#')
                    p2[++ct2].first=i,p2[ct2].second=j;
                else if(Map[i][j]=='*')
                    p1[++ct1].first=i,p1[ct1].second=j;
                else
                    vis[Map[i][j]-'0']++;
            }
        }
        dfs(1);
        ans/=a(ct1+ct2,ct1);
        printf("%.8f\n",ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值