链接:http://poj.org/problem?id=2585
题意:
某个人有一个屏幕大小为4*4的电脑,他很喜欢打开窗口,他肯定打开9个窗口,每个窗口大小2*2。并且每个窗口肯定在固定的位置上(见题目上的图),某些窗口可以覆盖另一些窗口(可以脑补)。询问给出的电脑屏幕是否是合法的。
分析:
可以预先处理出每个格子应该有哪几个窗口在这上面,将最上面的窗口与其他窗口连边,得到一张图,用拓扑判环,因为这道题太简单了,所以我就写这么短的题解。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<vector> 6 #include<queue> 7 #include<cmath> 8 using namespace std; 9 int a[5][5]; 10 queue <int> que; 11 vector<int> table[5][5]; 12 vector <int> g[20]; 13 14 int main(){ 15 for(int i=1;i<=9;i++){ 16 int x=ceil((double)i/3.0); 17 int y=i%3;if(!y)y=3; 18 table[x][y].push_back(i); 19 table[x+1][y].push_back(i); 20 table[x][y+1].push_back(i); 21 table[x+1][y+1].push_back(i); 22 }//预处理出每个格子应当有的窗口 23 string str; 24 while(cin >> str){ 25 int siz[20]; 26 int num=0; 27 memset(siz,0,sizeof(siz)); 28 for(int i=1;i<=9;i++) g[i].clear(); 29 if(str=="ENDOFINPUT")return 0; 30 memset(a,0,sizeof(a)); 31 for(int i=1;i<=4;i++){ 32 for(int j=1;j<=4;j++){ 33 cin>>a[i][j]; 34 } 35 } 36 for(int i=1;i<=4;i++){ 37 for(int j=1;j<=4;j++){ 38 for(int k=0;k<table[i][j].size();k++){ 39 if(table[i][j][k]==a[i][j])continue; 40 g[a[i][j]].push_back(table[i][j][k]);//连边 41 siz[table[i][j][k]]++; 42 } 43 } 44 } 45 for(int i=1;i<10;i++){ 46 if(!siz[i])que.push(i); 47 } 48 while(!que.empty()){//topu判环 49 int k=que.front(); 50 que.pop(); 51 num++; 52 for(int i=0;i<g[k].size();i++){ 53 siz[g[k][i]]--; 54 if(!siz[g[k][i]])que.push(g[k][i]); 55 } 56 } 57 if(num==9){ 58 cout<<"THESE WINDOWS ARE CLEAN "; 59 }else cout<<"THESE WINDOWS ARE BROKEN "; 60 string str; 61 cin >> str; 62 } 63 }