您的位置:首页 > 其它

Door Man poj 1300

2013-11-02 13:45 393 查看
题目大意: 沿着一个通道,穿过这些大房间,并把房门关上。你的问题是能否找到一条路径经过所有开着门的房间,并使得:

1) 通过门后立即把门关上;

2) 关上了的门不再打开;

3) 最后回到你自己的房间(房间0),并且所有的门都已经关闭了。


分析:本题实际上是判断一个图中是否存在欧拉回路或欧拉通路,要分两种情况考虑:

1)如果所有的房间都有偶数个门(通往其他房间),那么有欧拉回路,可以从0号房间出发,回到0号房间。但是这种情况下,出发的房间必须为0,因为要求回到0号房间。例如,第1个测试数据所对应的图为图5.6(a),图中有浅色阴影的顶点(即顶点0),表示管家初始时所处的房间;在该测试数据中,管家可以回到0号房间。

2)有两个房间的门数为奇数,其余的都是偶数,如果出发的房间和0号房间的门数都是奇数,那么也可以从出发的房间到达0号房间,并且满足题目要求。但是不能从房间0出发,必须从另一个门数为奇数的房间出发。例如第2、3个测试数据就是这种情形,对应的图为图(b)和图(c),输出的结果分别是"NO"和"YES
7"。



本题的难点在于输入数据的处理:

1) 因为有空行,而且这些空行都是有用的信息。由于有空行,所以不能简单地用cin读入每个房间有门通往其他房间的房间号;

2) 一行数据中既有字符型数据,又有数值型数据。比如START 1 2,必须区分不同类型的数据。

因此,必须采用cin.getline函数或者getchar函数将输入数据读入到字符数组buf中,再采用sscanf函数从buf中读出有用的数据。

sscanf()函数的用法:
http://blog.csdn.net/hearthougan/article/details/14054415
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>

using namespace std;

int readLine( char *s )//以字符形式读入每行数据并返回字符串的长度
{
int L;
for(L = 0; ( s[L] = getchar() ) != '\n' && s[L] != EOF; ++L)
;
s[L] = 0;
return L;
}

int main()
{
int i, j;
char buf[128];
int M, N;//M为管家的起始房间号,N为房间总数
int door[20];//记录每个房间的门数

while( readLine( buf ) )
{
if(buf[0] == 'S')
{
sscanf( buf, "%*s %d %d", &M, &N);
memset(door, 0, sizeof(door));

int doors = 0;//存放门的总数目
for(i = 0; i < N; ++i)
{
readLine( buf );
int k = 0;//读取数据的起始位置
//读取每个房间有门通往其他房间的房间号
while( sscanf(buf+k, "%d", &j) == 1 )
{
doors++;
door[i]++;
door[j]++;
//	cout<<"*************"<<endl;
//	cout<<"door["<<i<<"] = "<<door[i]<<" door["<<j<<"] = "<<door[j]<<endl;
//	cout<<"buf["<<k<<"] = "<<buf[k]<<endl;
//	cout<<"*************"<<endl;
while( buf[k] && buf[k] !=' ' )
k++;
//	cout<<"*************"<<endl;
//	cout<<"buf["<<k<<"] = "<<buf[k]<<endl;
//	cout<<"*************"<<endl;
while( buf[k] && buf[k] == ' ' )
k++;
}
}
readLine( buf );//读入"END"
int odd = 0, even = 0;//odd奇点的个数,even偶点的个数
for(i = 0; i < N; ++i)
{
if(door[i] % 2 == 0)
even++;
else
odd++;
}
if(odd == 0 && M == 0)
cout<<"YES "<<doors<<endl;
else if(odd == 2 && door[M] % 2 == 1 && door[0] % 2 == 1 && M != 0)
cout<<"YES "<<doors<<endl;
else
cout<<"NO"<<endl;
}
else if( !strcmp(buf, "ENDOFINPUT") )
break;
}
system("pause");
return 0;
}

/**

START 1 2
1

END
START 0 5
1 2 2 3 3 4 4

END
START 0 10
1 9
2
3
4
5
6
7
8
9

END
ENDOFINPUT

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: