Door Man——单笔画关门

来源:互联网 发布:高原红怎么去除知乎 编辑:程序博客网 时间:2024/04/30 20:47
Door Man
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 2358 Accepted: 937

Description

You are a butler in a large mansion. This mansion has so many rooms that they are merely referred to by number (room 0, 1, 2, 3, etc...). Your master is a particularly absent-minded lout and continually leaves doors open throughout a particular floor of the house. Over the years, you have mastered the art of traveling in a single path through the sloppy rooms and closing the doors behind you. Your biggest problem is determining whether it is possible to find a path through the sloppy rooms where you: 

  1. Always shut open doors behind you immediately after passing through 
  2. Never open a closed door 
  3. End up in your chambers (room 0) with all doors closed 

In this problem, you are given a list of rooms and open doors between them (along with a starting room). It is not needed to determine a route, only if one is possible. 

Input

Input to this problem will consist of a (non-empty) series of up to 100 data sets. Each data set will be formatted according to the following description, and there will be no blank lines separating data sets. 
A single data set has 3 components: 

  1. Start line - A single line, "START M N", where M indicates the butler's starting room, and N indicates the number of rooms in the house (1 <= N <= 20). 
  2. Room list - A series of N lines. Each line lists, for a single room, every open door that leads to a room of higher number. For example, if room 3 had open doors to rooms 1, 5, and 7, the line for room 3 would read "5 7". The first line in the list represents room 0. The second line represents room 1, and so on until the last line, which represents room (N - 1). It is possible for lines to be empty (in particular, the last line will always be empty since it is the highest numbered room). On each line, the adjacent rooms are always listed in ascending order. It is possible for rooms to be connected by multiple doors! 
  3. End line - A single line, "END" 

Following the final data set will be a single line, "ENDOFINPUT". 

Note that there will be no more than 100 doors in any single data set.

Output

For each data set, there will be exactly one line of output. If it is possible for the butler (by following the rules in the introduction) to walk into his chambers and close the final open door behind him, print a line "YES X", where X is the number of doors he closed. Otherwise, print "NO".

Sample Input

START 1 21ENDSTART 0 51 2 2 3 3 4 4ENDSTART 0 101 923456789ENDENDOFINPUT

Sample Output

YES 1NO

YES 10

昨天接触了欧拉回路和欧拉通路,学习了一下就做了这道题目。

题意:一共有m个门,从第n个门出发,穿过一个通道,一次性把这些门都关上,在这个过程中满足下面的要求(1)通过门后立即把门关上(2)关上的门不在打开(3)最后回到0房间,并且所有的门都已经关闭了。

解析:以房间为顶点,门为边构造图,一扇门就是一条边,从一个顶点出发,每条边走一次,最后回到0点,根据题意,可知这是一道求欧拉通路或是欧拉回路的问题,关于欧拉路的总结,还请看个人博客。

通过统计奇度点和偶度点的个数,满足欧拉路的只有三种情况,一种是只有偶度点,从0点出发,最后回到0点,一种是有且只有两个奇度点,如果出发的房间和0号房间的度数为奇度,可以从出发的房间到达0号房间,但不能从0号房间出发到达0号房间。

处理:根据题意,有m个门,输入的时候就输入n行,分别为和这个门相连的其他门的编号,并且都要大于这扇门,如果没有,那么就输入空行,所以在这个题目中,空行也是有作用的,所以要特殊处理,具体看代码啦。

#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;int main(){    int bj[50],n,m;    int i,j,l,doors;    char sz[100];    while(gets(sz))    {        if(strcmp(sz,"ENDOFINPUT") == 0)            break;        if(sz[0]=='S'&&sz[1]=='T'&&sz[2]=='A'&&sz[3]=='R'&&sz[4]=='T')        {            n = -1;m = -1;            for(i = 5;sz[i] != '\0';i++)            {                if(sz[i] >= '0' && sz[i] <= '9')                {                    if(n == -1)                        n = sz[i] - '0';                    else if(n >= 0 && m == -1)                        m = sz[i] - '0';                }            }            doors = 0;            memset(bj,0,sizeof(bj));            l = -1;        }        else if(strcmp(sz,"END") == 0)        {            int odd = 0,even = 0;            for(j = 0; j < m; j++)            {                if(bj[j] % 2)                {                    odd++;//奇数加加                }                else                    even++;//偶数加加            }            if(odd == 0 && n == 0)                printf("YES %d\n",doors);//一旦成功,肯定所有的门都关上了额。。。。。。            else if(odd == 2 && bj[n]%2==1 &&bj[0]%2==1&&n!=0)                printf("YES %d\n",doors);            else                printf("NO\n");        }        else        {            l++;            for(i = 0;sz[i] != '\0';i++)            {                if(sz[i] >= '0' && sz[i] <= '9')                {                    doors++;                    bj[sz[i] - '0']++;                    bj[l]++;                }            }        }    }return 0;}


0 0