POJ 2585 Window Pains 拓扑排序

题目大意:给出电脑屏幕上的若干窗口图形,窗口关系只能是覆盖和被覆盖,问是否合理.

题解:熟练拓扑排序.

#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;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值