传送门:题目
题意:
给[1,3]行,每行6个数字,每行出一个数字,(同一行最多出一个数字,其他行可以不出。)组成一个数x,问这个数x最大能有多少,前提是这个数x之前的每一个数都能被组成。
题解:
我们先考虑这样一个问题,我们现在只知道有三行,每行6个数字,但不知道每个数字具体是多少,问:满足题目规则的情况下,x最大是多少?
如果每行有9个数字,那肯定是999
我们考虑,假如,现在最大值是100,那么:
[11,22,33,44,55,66,77,88,99]肯定都能被组成
组成上面的9个数需要多少个数字呢?
,而我们一共有多少个数呢?
我们还需要数字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;
}