NOJ[1318] First Choice

  • 问题描述
  • So clever the Wodex and his partners were! They got the right sort of values. But not over yet. 

    What happened? The castle was shaking! Suddenly, the castle collapsed and they were swallowed up by dark. 
    When they waked up, they found they were surrounded by lots of tall walls. 

    At the same time, horn sounded: 
    If you want to beat me, you should pass this level. Look at the map, there is a M * N maze, later you will be appeared in the map, each 1 * 1 lattice in the map means a room. There are only two characters 'X' and 'O' in the map, 'X' means that room is bad and you can not get in; 'O' means intact room that you can get in. There will must be a door and only one door between two adjoining and intact rooms. At the beginning, all of doors are opened, if you walk from one intact room to the adjoining and intact room, the door between them will close, that means you can not go again from these two rooms. Only all of doors are closed, you can be deliveried out of the maze and you will see me. 
    Look, there is a transfer machine next to you, you can use it to choose any one room to get in the maze and you will start at that room. 
    How can you walk to open all of doors? Start now! 

  • 输入
  • There will be several test cases. 
    First line will contain two integers M (0 < M < 100) and N (0 < N < 100). 
    Then M lines, each line N characters, only contain 'O' and 'X'. 
  • 输出
  • If they can open all of doors, print 'YES', otherwse print 'NO'. 
    There will be at least one intact room. 
  • 样例输入
  • 5 6
    OXXXOO
    OXXXXO
    OOOOOO
    XXXXXX
    XXXXXX
    3 3
    OOO
    OOO
    OOO
    3 3
    OOO
    XXX
    OOO
  • 样例输出
  • YES
    NO
    NO
  • 提示
  • 来源
  • Hungar
如果是欧拉通路就可以,所以只要判断图的连通性和奇度点的个数就行了。

#include<stdio.h>
#include<string.h>

struct node
{
int x,y;
bool operator != (node a)
{
return x!=a.x || y!=a.y;
}
}father[105][105];

char mat[105][105];

int dir[4][2]={1,0,-1,0,0,1,0,-1};

int m,n;

node find(int x,int y)
{
if(x == father[x][y].x && y == father[x][y].y)
return father[x][y];
father[x][y]=find(father[x][y].x,father[x][y].y);
return father[x][y];
}
bool is_legal(int x,int y)
{
return x>=0 && x<m && y>=0 && y<n;
}
void unit()
{
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
father[i][j].x=i;
father[i][j].y=j;
}
}

void Union(int x1,int y1,int x2,int y2)
{
node a=find(x1,y1);
node b=find(x2,y2);
if(a != b)
{
father[a.x][a.y].x=b.x;
father[a.x][a.y].y=b.y;
}
}

int main()
{
while(~scanf("%d%d",&m,&n))
{
unit();
for(int i=0;i<m;i++)
scanf("%s",mat[i]);
int cnt=0;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
if(mat[i][j]=='O')
{
int t=0;
for(int k=0;k<4;k++)
{
int x=i+dir[k][0];
int y=j+dir[k][1];
if(is_legal(x,y) && mat[x][y]=='O')
{
t++;
Union(i,j,x,y);
}
}
if(t%2)
cnt++;
}
}
if(cnt>2)
printf("NO\n");
else
{
int t=0;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
if(mat[i][j]=='O' && father[i][j].x == i && father[i][j].y == j)
t++;
}
if(t==1)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值