poj 2023 Choose Your Own Adventure(数据结构+深度搜索)

Choose Your Own Adventure
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 1559   Accepted: 638

Description

After reading the book Tim and Marc Kill Kenny about fifty zillion times, James decided he'd had it with choose-your-own-adventure stories. No matter what choices he made, it seemed like Kenny always fell down an abandoned mine shaft, got run over by a bus load of nuns, or was messily devoured by stray cats. James eventually found the page with the happy ending (where Kenny saves himself by trapping Tim and Marc between the pizza and the hungry programmers) by flipping through the book, but he can't figure out how to get there by following the rules. Luckily, he owns a C compiler...

Input

Input to this problem will consist of a (non-empty) series of up to 100 data sets, each representing a choose-your-own-adventure story. Each data set will be formatted according to the following description, and there will be no blank lines separating data sets.

The first line contains a single integer n indicating the number of data sets.

A single data set has 2 components:
  1. Page Count - A line containing a single integer X, where 1 < X < 100, indicating the number of pages in the story.
  2. Page List - A sequence of X lines, each of which represents a page from the book. Each line has the following components separated from one another by single spaces:
    • Line type - A single character indicating what type of line this is. It will represent either a "C" choice page, or an "E" end page. Page 1 is always a choice page.
    • Text - A string of text surrounded by double quotes. Including the quotes, this component will not exceed 256 characters. The quotes are given for input purposes only and should not be considered part of the text. The text will not contain embedded double quotes.
    • Choices - Two positive integers from 1 to X indicating the pages where the reader can go from this page. Only choice pages have this component.
    • Ending Type - Either the text "HAPPY" or "GRISLY". There will only be one happy ending per story, and only end pages have this component.

Output

For each story in the input:
  1. Output a single line, "STORY #" where # is 1 for the first story, 2 for the second story, etc.
  2. Determine the story that begins on page 1 and ends on the happy ending page. Output the text of this story, printing one "page" of text per line. Note that there is only one such story for each data set.

Sample Input

2
3
C "Arrived at LSU for the contest" 2 3
E "Was devoured by sidewalk ants" GRISLY
E "Won the contest. Received glory and nachos." HAPPY
5
C "Saw a peanut" 3 5
E "Made peanut butter sandwich" HAPPY
C "Found a hammer" 4 2
E "Hit self on head with hammer, ouch!" GRISLY
E "Ate the peanut, choked on it, and died" GRISLY

Sample Output

STORY 1
Arrived at LSU for the contest
Won the contest. Received glory and nachos.
STORY 2
Saw a peanut
Found a hammer
Made peanut butter sandwich

题意理解:
(1)每一个测试组只有一个结果,即搜索到结果后就可以安全退出
(2)每次都是从第一页开始搜索的,不要找搜索位置,从第一页开始即可
(4)每一组字符串是一个故事,前边C表示后边有两个整数,是可以读的下一页的页码,这里行数索引值代表页码,E表示这是一个结束页
(5)后边是happy就是要搜索的退出条件,一个完美的结局,若不是happy则返回上级从新搜索

Source

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;

//定义页,存放输入的行数信息
typedef struct
{
    int next1,next2;
    char type;
    string text;
    string end;
}Page;


Page page[101];
//标记这个页数是否读过,0表示未读过,1表示已读过
int mark[101];
//存放路径,值0时表示到尾部
int path[101];

void init()
{
    for(int i = 0;i < 101; i++)
    {
        page[i].end = "";
        page[i].text = "";
        page[i].next1 = 0;
        page[i].next2 = 0;
        mark[i] = 0;
        path[i] = 0;
    }
}

//深度搜索,p表示下一页要读的页码索引,k表示路径长度,读到了第几页,每加一页k+1
bool dfs(int p,int k)
{
    //如果读过,就直接返回上级
    if(mark[p]==1)
    return false;
    //记录路径,第k路径是第P页
    path[k] = p;
    //标记这一页读过
    mark[p] = 1;
    //读到故事结尾了,返回true
    if(page[p].type=='E'&&page[p].end.compare("HAPPY")==0)
    return true;
    if(page[p].type == 'C')
    {
        //此条路径成功返回true,因为每组数据只有一个结局,所以找到后即返回,不用再搜索了。
        if(dfs(page[p].next1,k+1))
        return true;
        if(dfs(page[p].next2,k+1))
        return true;
    }
    //这条路径没有成功的完美故事结局,这条路径返回初始值,标记为未读,路径复位0
    path[k] = 0;
    mark[p] = 0;
    return false;
}
//打印
void print()
{
    int i = 1;
    while(path[i]!=0)
    {
        cout<<page[path[i]].text<<endl;
        i++;
    }
}

int main()
{
    //测试数据组数
    int n;
    //页数
    int x;
    //页码
    int page1,page2;
    //内容
    string text,end;

    //行数
    string line;
    cin>>n;
    for(int m = 1; m <= n; m++)
    {
        cin>>x;
        //回车符
        getchar();
        //初始化
        init();
        for(int i = 1; i <= x; i++)
        {
            //一次读一行
            getline(cin,line);
            //如果是C则按照C行格式初始化,先截取字符串,放在一个结构体中
            if(line[0] == 'C')
            {
                page1 = atoi(line.substr(line.find_last_of("\"")+2,1).c_str());
                page2 = atoi(line.substr(line.find_last_of("\"")+4,1).c_str());
                text = line.substr(line.find_first_of("\"")+1,line.find_last_of("\"")-line.find_first_of("\"")-1);
                page[i].next1 = page1;
                page[i].next2 = page2;
                page[i].text = text;
                page[i].type = 'C';
            }else if(line[0] == 'E')
            {
                //如果是E则按照E行格式初始化,先截取字符串,放在一个结构体中
                text = line.substr(line.find_first_of("\"")+1,line.find_last_of("\"")-line.find_first_of("\"")-1);
                end = line.substr(line.find_last_of("\"")+2,line.length()-line.find_last_of("\""));
                page[i].end = end;
                page[i].text = text;
                page[i].type = 'E';
            }
            //把流和内容清空,注意,不然下次读完之后,内容有重复
            line = "";
            cin.clear();
        }
        //从书的第一页开始搜索
        mark[1] = 1;
        path[1] = 1;
        cout<<"STORY "<<m<<endl;
        if(dfs(page[1].next1,2))
        print();
        else
        {
            if(dfs(page[1].next2,2))
            print();
        }

    }
    return 0;
}

你可能感兴趣的:(数据结构)