Codeforces 887B 暴力

博客介绍了如何解决Codeforces上的887B问题,通过分析行数和数字限制,推导出最大可能的数不超过100,并采用暴力模拟的方法找出所有可能的组合。最终提供了一段AC代码实现该策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门:题目

题意:

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

题解:

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

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

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

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

组成上面的9个数需要多少个数字呢? 92=18 9 ∗ 2 = 18 ,而我们一共有多少个数呢? 36=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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值