链接:http://poj.org/problem?id=2585
题意:
某个人有一个屏幕大小为4*4的电脑,他很喜欢打开窗口,他肯定打开9个窗口,每个窗口大小2*2。并且每个窗口肯定在固定的位置上(见题目上的图),某些窗口可以覆盖另一些窗口(可以脑补)。询问给出的电脑屏幕是否是合法的。
分析:
可以预先处理出每个格子应该有哪几个窗口在这上面,将最上面的窗口与其他窗口连边,得到一张图,用拓扑判环,因为这道题太简单了,所以我就写这么短的题解。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
int a[][];
queue <int> que;
vector<int> table[][];
vector <int> g[]; int main(){
for(int i=;i<=;i++){
int x=ceil((double)i/3.0);
int y=i%;if(!y)y=;
table[x][y].push_back(i);
table[x+][y].push_back(i);
table[x][y+].push_back(i);
table[x+][y+].push_back(i);
}//预处理出每个格子应当有的窗口
string str;
while(cin >> str){
int siz[];
int num=;
memset(siz,,sizeof(siz));
for(int i=;i<=;i++) g[i].clear();
if(str=="ENDOFINPUT")return ;
memset(a,,sizeof(a));
for(int i=;i<=;i++){
for(int j=;j<=;j++){
cin>>a[i][j];
}
}
for(int i=;i<=;i++){
for(int j=;j<=;j++){
for(int k=;k<table[i][j].size();k++){
if(table[i][j][k]==a[i][j])continue;
g[a[i][j]].push_back(table[i][j][k]);//连边
siz[table[i][j][k]]++;
}
}
}
for(int i=;i<;i++){
if(!siz[i])que.push(i);
}
while(!que.empty()){//topu判环
int k=que.front();
que.pop();
num++;
for(int i=;i<g[k].size();i++){
siz[g[k][i]]--;
if(!siz[g[k][i]])que.push(g[k][i]);
}
}
if(num==){
cout<<"THESE WINDOWS ARE CLEAN\n";
}else cout<<"THESE WINDOWS ARE BROKEN\n";
string str;
cin >> str;
}
}