[SMOJ1726]染色一

来源:互联网 发布:centos 5.5 下载地址 编辑:程序博客网 时间:2024/05/18 14:15

题目描述

有一个NN列的表格,每个格子刚开始都是白色的(用数字0表示)。每轮染色是:
1、每次你选择表格中的任意一个长方形(正方形也可以认为是长方形),长方形的4条边必须是水平的或者竖直的。
2、然后给该长方形内部染成一种颜色,颜色用数字1至9表示。

总共染色9轮,每轮只使用一种颜色,每种颜色只用一次,注意:同一个格子,后染的颜色会把该格子之前染的颜色覆盖掉。
例如:
第1轮染色(用颜色2)后是:
2220
2220
2220
0000
第2轮染色(颜色7)后是:
2220
2777
2777
0000
第3轮染色(用颜色3)后是:
2230
2737
2777
0000

现在给出经过9轮染色之后的表格的各个格子的最终颜色,在最终你能看到的那些颜色当中(例如在上面例子中,最终你能看到的颜色是2,3,7),
有多少种颜色可能是第1轮染色过程中使用的颜色?

输入格式 1726.in

第一行,一个整数N1N10
接下来是NN列的表格,表示经过9轮染色之后,各个格子的最终颜色,每个格子的最终颜色是0至9。

输出格式 1726.out

一个整数。

输入样例 1726.in

4
2230
2737
2777
0000

输出样例 1726.out

1

样例说明

颜色3不可能是第一轮染色使用的颜色,颜色7不可能是第一轮染色使用的颜色,只有颜色2可能是第一轮染色使用的颜色。所以输出1。


可以看到,这题的数据范围非常小,完全可以直接用搜索做,枚举可能的颜色并判断即可。

判断这里有点小问题。直接判断某种颜色是否可能为第一种颜色是不容易写的,不妨换个角度考虑。其实可以采用排除法,对于某两种颜色,如果在一种颜色 i 的范围内出现了另一种颜色 j ,那么显然颜色 j 覆盖了颜色 i ,可以将 j 排除掉。

为了方便,可以先预处理出每种颜色出现的位置范围。总的时间复杂度为 O(n4)

参考代码:

#include <algorithm>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>using namespace std;const int maxn = 10 + 5;int n;char a[maxn][maxn];int minx[maxn], maxx[maxn], miny[maxn], maxy[maxn];bool f[maxn];bool check(int n1, int n2) {    for (int i = minx[n1]; i <= maxx[n1]; i++)        for (int j = miny[n1]; j <= maxy[n1]; j++)            if (n2 + '0' == a[i][j]) return true;    //printf("%d %d\n", n1, n2);    return false;}int main(void) {    freopen("1726.in", "r", stdin);    freopen("1726.out", "w", stdout);    scanf("%d", &n);    memset(minx, 0x7f, sizeof minx); memset(miny, 0x7f, sizeof miny);    for (int i = 1; i <= n; i++) {        scanf("%s", a[i] + 1);        for (int j = 1; j <= n; j++) {            int num = a[i][j] - '0'; f[num] = true;            minx[num] = min(minx[num], i); maxx[num] = max(maxx[num], i);            miny[num] = min(miny[num], j); maxy[num] = max(maxy[num], j);        }    }    for (int i = 1; i < 10; i++)        if (maxx[i]) {            bool bo = true;            for (int j = 1; j < 10 && bo; j++)                if (i != j && maxx[j])                    if (check(i, j)) f[j] = false;        }    int ans = 0;    for (int i = 1; i < 10; i++) if (f[i]) /*printf("%d ", i), */ans += f[i];    printf("%d\n", ans);    return 0;}
0 0
原创粉丝点击