Window Pains
题目链接:在这里
思路:
本题最难的就是建图了,完全没看出来是拓扑排序。。
那么为什么是拓扑排序呢?
我们看,在1~9每个窗口的区域里,如果整个区域a是相同的数,那么这时这个窗口肯定是后打开的。如果这个区域里面还有其他的数(例如b,c…),那么其他窗口肯定是在这个窗口后面打开的。由此可建立有向边(a->b,a->c….)
建完图后,只需要判断这个图是否为DAG即可(有向无环图)
代码:
#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
int mp[6][6],in[10];
int dx[]= {0,0,1,1};
int dy[]= {0,1,0,1};
vector<int>v[10];
void add_edge()
{
memset(in,0,sizeof(in));
for(int i=0; i<10; ++i)
v[i].clear();
for(int i=1; i<=9; ++i)
{
int x=(i+2)/3;
int y=i%3==0?3:i%3;
for(int j=0; j<4; ++j)
{
int tx=x+dx[j];
int ty=y+dy[j];
if(mp[tx][ty]!=i)
{
v[i].push_back(mp[tx][ty]);
++in[mp[tx][ty]];
}
}
}
}
int solve()
{
add_edge();
queue<int>q;
for(int i=1; i<=9; ++i)
if(!in[i])
q.push(i);
int num=9;
while(!q.empty())
{
int u=q.front();
q.pop(),--num;
for(int i=0; i<v[u].size(); ++i)
{
--in[v[u][i]];
if(!in[v[u][i]])
q.push(v[u][i]);
}
}
if(num>0)
return 0;
return 1;
}
int main()
{
char s[110];
while(~scanf("%s",s))
{
if(!strcmp(s,"ENDOFINPUT"))
return 0;
for(int i=1; i<=4; ++i)
for(int j=1; j<=4; ++j)
scanf("%d",&mp[i][j]);
scanf("%s",s);
int ans=solve();
if(ans)
printf("THESE WINDOWS ARE CLEAN\n");
else
printf("THESE WINDOWS ARE BROKEN\n");
}
return 0;
}