题目链接;
POJ 2585 Window Pains
题意:
给一个
4∗4
的方格表示屏幕,
1−−9
每个数字可以用
2∗2
的方格出现在屏幕上的特定位置,让你判断这个屏幕是否合法。
分析:
这题难点在于建立相对顺序。
首先我们可以把每个位置可以出现的数字预处理出来。
然后判断每个位置出现的数字,比如说在
(2,2)
位置可以出现:
1,2,4,5
。如果实际出现的数是:
4
,那么我们就可建立相对优先顺序:
我们对每个位置都这样处理,然后拓扑排序判断是否有环就好了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <climits>
#include <cmath>
#include <ctime>
#include <cassert>
#include <vector>
#include <queue>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
const int MAX_N = 20;
char s[50];
int data[10][10];
string can[10][10];
int degree[MAX_N];
vector<int> vec[MAX_N];
queue<int> que;
void init()
{
can[0][0] = "1\0", can[0][3] = "3\0", can[3][0] = "7\0", can[3][3] = "9\0";
can[0][1] = "12\0", can[0][2] = "23\0", can[1][0] = "14\0", can[1][3] = "36\0";
can[2][0] = "47\0", can[2][3] = "69\0", can[3][1] = "78\0", can[3][2] = "89\0";
can[1][1] = "1245\0", can[1][2] = "2356\0";
can[2][1] = "4578\0", can[2][2] = "5689\0";
}
bool TopoSort(int n)
{
while(!que.empty()) que.pop();
for(int i = 1; i <= n; ++i) {
if(degree[i] == 0) que.push(i);
}
while(!que.empty()) {
int cur = que.front();
que.pop();
for(int i = 0; i < vec[cur].size(); ++i) {
int to = vec[cur][i];
degree[to]--;
if(degree[to] == 0) que.push(to);
}
}
for(int i = 1; i <= n; ++i) {
if(degree[i] > 0) {
//printf("i = %d\n");
return false;
}
}
return true;
}
int main()
{
init();
while(~scanf("%s", s)) {
if(strcmp(s, "ENDOFINPUT\0") == 0) break;
int flag = 0;
for(int i = 0; i < 4; ++i) {
for(int j = 0; j < 4; ++j) {
scanf("%s", s);
if(flag) continue; //already illeagal
if(strlen(s) > 1 || !isdigit(s[0])) flag = 1;
else data[i][j] = s[0] - '0';
}
}
scanf("%s", s);
if(flag) {
printf("THESE WINDOWS ARE BROKEN\n");
continue;
}
for(int i = 0; i < 10; ++i) {
vec[i].clear();
degree[i] = 0;
}
// check number
for(int i = 0; i < 4; ++i) {
for(int j = 0; j < 4; ++j) {
flag = 0;
//printf("i = %d j = %d t = %d:", i, j, data[i][j]);
int t = data[i][j], len = can[i][j].length();
for(int k = 0; k < len; ++k) {
int tt = can[i][j][k] - '0';
//printf(" %d", tt);
if(t == tt) flag = 1;
else {
degree[tt]++;
vec[t].push_back(tt);
}
}
//printf("\n");
if(flag == 0) break;
}
if(flag == 0) break;
}
if(flag && TopoSort(9)) {
printf("THESE WINDOWS ARE CLEAN\n");
}else {
printf("THESE WINDOWS ARE BROKEN\n");
}
}
return 0;
}