Booklist——ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛 A

  • 题目链接:
    https://hihocoder.com/problemset/problem/1383

  • 分析:
    给出很多行字符串,数量未知,最后一行为单个的0,结束一次样例。每一行字符串由 斜杠,空格,大写字母,数字组成。斜杠之前的字符串为目录,最后一个斜杠后的字符串为书名。要求把书名和字符串按字典序分别输出,目录在书名前。输入格式看题目样例。

  • 题解:
    比赛时被坑死了,强行WA啊。。。
    首先注意是一行一行读入,所以必须得用 getline(cin,str).
    然后还有一个坑点就是书名和目录名不一样,书名需要在目录名后输出!

    这样先给所有字符串字典序排序后读入字典树输出即可。字典树排序需要注意空格的ASCII 码在斜杠前,所以排序之前需要替换一下,排完序后再换回来,然后由于书名和目录名不一样,那么每个书名后(即每行字符串后)都 加上一个比其他字符都大的(我加的‘a’),再排序。输出的时候删除末尾的一个字符就行。

  • AC代码:
    这里写图片描述

/*************************************************************************
    > File Name: test.cpp
    > Author: Akira 
    > Mail: qaq.febr2.qaq@gmail.com 
 ************************************************************************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <ctime>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))
using namespace std;

#define MaxN 100000
#define MaxM MaxN*10
#define INF 0x3f3f3f3f
#define bug cout<<88888888<<endl;

string tree[33];

struct node
{
    int num;
    node *son[60];
    string sss;
    node()
    {
        num=0;
        int i;
        for(i=0;i<=50;i++)
            son[i]=NULL;
    }
};


node * root = new node;
node * cur  = new node;
node * NewNode = new node;

void insert(string str)
{
    int i = 0;
    int m;
    cur=root;
    string tmp;
    while(i<str.length())
    {
        while( str[i] != '+' && i<str.length()){
            tmp += str[i];
            i++;
        }
        while( str[i] == '+'  && i<str.length() ) i++;
        //cout << i << endl;
        m = 0;
        for(int j=1;j<=cur->num;j++)
        {
            if(cur->son[j]->sss == tmp )
            {
                m = j;
                break;
            }
        }
        if(m ==0){
             m = ++cur->num;
        }

        if(cur->son[m]!=NULL)
        {
            cur=cur->son[m];
            cur->sss = tmp;
        }
        else
        {
            NewNode=new node;
            cur->son[m]=NewNode;
            cur=NewNode;
            cur->sss = tmp;
        }
        tmp.clear();
    }
}

void dfs(node *t, int lel)
{
    for(int i=1;i<=t->num;i++)
    {
        if(t->son[i]->num>0)
        {
            for(int k=1; k<= lel*4; k++)
            {
                cout << " ";
            }
            cout << t->son[i]->sss << endl;
            dfs(t->son[i], lel+1);
        }
    }
    for(int i=1;i<=t->num;i++)
    {
        if(t->son[i]->num == 0)
        {
            for(int k=1; k<= lel*4; k++)
            {
                cout << " ";
            }
            t->son[i]->sss.erase(t->son[i]->sss.end()-1);
            cout << t->son[i]->sss << endl;
        }
    }
}


int main()
{
    string str;
    int cnt = 0;
    int tt = 1;
    while(cin>>str)
    {
        if(str[0] == '0' && str.length() == 1)
        {
            sort(tree, tree+cnt);
            for(int i=0;i<cnt;i++)
            {
                for(int j=0;j<tree[i].length();j++)
                {
                    if(tree[i][j] == '.') tree[i][j] = ' ';
                }
                insert(tree[i]);
            }

            cout << "Case " << tt++ <<":\n";
            dfs(root,0);
            cnt = 0;
            root = new node;
            cur  = new node;
            NewNode = new node;
            for(int i=0;i<=30;i++)
                tree[i].clear();
            continue;
        }
        else
        {
            str+='a';
            for(int i=0;i<str.length();i++)
            {
                if(str[i] == '/') str[i] = '+';
                if(str[i] == ' ') str[i] = '.';
            }
        }
        tree[cnt++] = str;
    }
    system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值