题目大意:在4*4的屏幕上操作9个2*2的窗口,后打开的窗口会覆盖之前打开的窗口,问最后屏幕中呈现的样子可不可能发生
输入:(可以有很多case,个数不超过100个)
START
最终屏幕的第i行(共4行,每行4个数字,数字1~9分别代表9个窗口)
END
ENDOFINPUT(以这行结束)
输出:THESE WINDOWS ARE CLEAN/THESE WINDOWS ARE BROKEN
分析:拓扑排序的应用。由于事件活动发生有先后顺序,且这个顺序不能产生矛盾的情况,所以我们知道用拓扑排序来解决问题。因为窗口都是开着的,所以最终屏幕上呈现的数字一定覆盖了该位置可能出现的其他数字,也就是说最终状态数字是发生在其他数字之后的,建图时由覆盖数字指向被覆盖数字,建好图用拓扑排序判断图中是否有环,如果无环则说明OK。
屏幕中每个格子可以出现的数字如下:(建图就是最终屏幕上每个格子中的数字指向格子中可能出现的其他数字)
1 | 1,2 | 2,3 | 3 |
1,4 | 1,2,4,5 | 2,3,5,6 | 3,6 |
4,7 | 4,5,7,8 | 5,6,8,9 | 6,9 |
7 | 7,8 | 8,9 | 9 |
代码:转载自https://www.cnblogs.com/pony1993/archive/2012/08/16/2641904.html
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std;
const int N=5;
int map[10][10];//邻接矩阵
int screen[N][N];//屏幕最后显示的内容
string cover[N][N];//能覆盖(i,j)位置的窗口
string s;
int vis[10];//标记
int id[10];//入度
int t;//记录出现的窗口种类数
void cal(){//初始化cover(coverij储存ij位置可能出现的数字)
int k,i,j;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
cover[i][j].erase();
for(k=1;k<=9;k++){
i=(k-1)/3;
j=(k-1)%3;
cover[i][j]+=(char)(k);
cover[i][j+1]+=(char)(k);
cover[i+1][j]+=(char)(k);
cover[i+1][j+1]+=(char)(k);
}
}
void build(){//构造有向图
int i,j,k;
for(i=0;i<N-1;i++){
for(j=0;j<N-1;j++){ //遍历i行j列每个位置建图
for(k=0;k<cover[i][j].length();k++){ //从screen[i][j]到可能出现的数字建边
if((!map[screen[i][j]][cover[i][j][k]]) && (screen[i][j]!=cover[i][j][k])){
map[screen[i][j]][cover[i][j][k]]=1;
id[cover[i][j][k]]++; //入度
}
}
}
}
}
int topo(){//拓扑排序,判环
int i,j,k;
for(i=0;i<t;i++){ //一共有t个点有出度,所以
k=1;
while(!vis[k] || (k<=9&&id[k]>0)) //找出最终屏幕中出现的且入度为0的数字
k++;
if(k>9)
return 0; //存在环
vis[k]=0;
for(j=1;j<10;j++){ //删除入度为0的点邻接的边
if(vis[j]&&map[k][j]) //还在图中且与k点相邻的数字 入度减一
id[j]--;
}
}
return 1; //无环
}
int main(){
int i,j,k;
cal();
while(cin>>s){
if(s=="ENDOFINPUT")
break;
memset(id,0,sizeof(id));
memset(vis,0,sizeof(vis));
memset(map,0,sizeof(map));
t=0;
for(i=0;i<N-1;i++){
for(j=0;j<N-1;j++){
scanf("%d",&k);
if(!vis[k]){
t++; //记录出现的数字种类数
vis[k]=1;
}
screen[i][j]=k; //屏幕最终ij位置的数字
}
}
build();
if(topo())
puts("THESE WINDOWS ARE CLEAN");
else
puts("THESE WINDOWS ARE BROKEN");
cin>>s;
}
return 0;
}