Codeforces 887B 暴力

传送门:题目

题意:

[1,3]行,每行6个数字,每行出一个数字,(同一行最多出一个数字,其他行可以不出。)组成一个数x,问这个数x最大能有多少,前提是这个数x之前的每一个数都能被组成。

题解:

我们先考虑这样一个问题,我们现在只知道有三行,每行6个数字,但不知道每个数字具体是多少,问:满足题目规则的情况下,x最大是多少?

如果每行有9个数字,那肯定是999

我们考虑,假如,现在最大值是100,那么:

[11,22,33,44,55,66,77,88,99]肯定都能被组成

组成上面的9个数需要多少个数字呢? 9 2 = 18 ,而我们一共有多少个数呢? 3 6 = 18
我们还需要数字0啊,[10,20,30之类的],反证法得到结论:最大数x小于100

明白上面的结论,我们就可以暴力的时候考虑一位或者两位的情况,而不需要考虑三位的情况。

我们只需要单纯的模拟一下题目的过程就好了,发现一个数,标记一下,跨行乘10就好了。
最后从1开始往后扫,如果该数没有标记,输出该数-1就好了。

AC代码:

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n, ans[4][7], vis[100];
    memset(vis, 0, sizeof(vis));
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= 6; ++j)
            scanf("%d", &ans[i][j]);

    for (int i = 1; i <= n; ++i) {//扫描每一行
        for (int j = 1; j <= 6; ++j) {//扫描每一列
            vis[ans[i][j]] = 1;//先标记单个数字
            for (int k = 1; k <= n; ++k) {//然后考虑跨行
                if (k == i) continue;//不能是本行
                for (int l = 1; l <= 6; ++l) {
                    vis[ans[i][j] * 10 + ans[k][l]] = 1;//因为最多是99,所以我们就不需要考虑三位的情况了
                }
            }
        }
    }
    for (int i = 1; i <= 99; ++i)
        if (!vis[i]) {
            printf("%d\n", i - 1);
            break;
        }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/shadandeajian/article/details/81638556
今日推荐