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
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 */
相关文章推荐
- POJ-1300-Door Man
- POJ 1300 Door Man
- poj1300 door man
- POJ 1300 Door Man(欧拉回路判定)
- POJ 1300 Door Man - from lanshui_Yang
- POJ 1300 Door Man (有向图欧拉通路)
- POJ 1300 Door Man 欧拉路的判断
- zoj 1395 && poj 1300 Door Man
- POJ 1300 Door Man(欧拉回路_格式控制*)
- POJ-1300 Door Man
- poj 1300 Door Man(欧拉回路判定)
- POJ 1300 Door Man - from lanshui_Yang
- poj 1300 Door man
- poj 1300 Door Man(欧拉回路判定)
- POJ 1300 Door Man 欧拉回路的判定
- Poj 1300 Door Man (欧拉回路 通路 stream处理输入)
- poj 1300 Door Man
- POJ 1300 Door Man(欧拉通路)
- POJ 1300 Door Man(欧拉通路)
- [欧拉回路] poj 1300 Door Man