题目大意:给出电脑屏幕上的若干窗口图形,窗口关系只能是覆盖和被覆盖,问是否合理.
题解:熟练拓扑排序.
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iomanip>
using namespace std;
class WindowPains
{
int have[6][6][5];//第三维表示个数
bool map[10][10];
void coordinate(int &,int &,int);
bool topo();
public:
WindowPains();
void work();
};
void WindowPains::coordinate(int &x,int &y,int i)
{
x=i%4;
if(x==0){y=i/4;x=4;}
else y=i/4+1;
}
WindowPains::WindowPains()
{
memset(have,0,sizeof(have));
int i,x,y;
for(i=1;i<=9;i++)
{
x=i%3;
if(x==0){y=i/3;x=3;}
else y=i/3+1;
have[x][y][++have[x][y][0]]=i;
x++;
have[x][y][++have[x][y][0]]=i;
x--;y++;
have[x][y][++have[x][y][0]]=i;
x++;
have[x][y][++have[x][y][0]]=i;
}
}
bool WindowPains::topo()
{
int out[10];
memset(out,0,sizeof(out));
int top=-1,i,j;
//获得每个顶点出度
for(i=1;i<=9;i++)
{
for(j=1;j<=9;j++)
{
if(i==j)continue;
if(map[j][i])out[i]++;
}
if(out[i]==0){out[i]=top;top=i;}//进栈
}
for(i=1;i<=9;i++)
{
if(top==-1)return false;//没有出度为零的点,有环
int _top=top;
top=out[top];//注意先出栈
for(j=1;j<=9;j++)
{
if(map[_top][j]==true&&_top!=j)out[j]--;//删边
if(out[j]==0)
{
out[j]=top;top=j;//入栈
}
}
}
return true;
}
void WindowPains::work()
{
memset(map,false,sizeof(map));
int i,j,x,y,k;
//建图
for(i=1;i<=16;i++)
{
cin>>k;
coordinate(x,y,i);
for(j=1;j<=have[x][y][0];j++)
map[k][have[x][y][j]]=true;
}
if(topo())cout<<"THESE WINDOWS ARE CLEAN"<<endl;
else cout<<"THESE WINDOWS ARE BROKEN"<<endl;
}
WindowPains W;
int main()
{
char s[20];
while(1)
{
cin>>s;
if(s[3]=='O')break;
W.work();
cin>>s;
}
return 0;
}