hihoCoder 1383 : The Book List 北京网络赛

http://hihocoder.com/problemset/problem/1383?sid=950389

#1383 : The Book List

时间限制:1000ms

单点时限:1000ms

内存限制:256MB

描述

The history of Peking University Library is as long as the history of Peking University. It was build in 1898. At the end of year 2015, it had about 11,000 thousand volumes of books, among which 8,000 thousand volumes were paper books and the others were digital ones. Chairman Mao Zedong worked in Peking University Library for a few months as an assistant during 1918 to 1919. He earned 8 Dayang per month there, while the salary of top professors in Peking University is about 280 Dayang per month.

Now Han Meimei just takes the position which Chairman Mao used to be in Peking University Library. Her first job is to rearrange a list of books. Every entry in the list is in the format shown below:

CATEGORY 1/CATEGORY 2/..../CATEGORY n/BOOKNAME

It means that the book BOOKNAME belongs to CATEGORY n, and CATEGORY n belongs to CATEGORY n-1, and CATEGORY n-1 belongs to CATEGORY n-2...... Each book belongs to some categories. Let‘s call CATEGORY1  "first class category", and CATEGORY 2 "second class category", ...ect. This is an example:

MATH/GRAPH THEORY
ART/HISTORY/JAPANESE HISTORY/JAPANESE ACIENT HISTORY
ART/HISTORY/CHINESE HISTORY/THREE KINDOM/RESEARCHES ON LIUBEI
ART/HISTORY/CHINESE HISTORY/CHINESE MORDEN HISTORY
ART/HISTORY/CHINESE HISTORY/THREE KINDOM/RESEARCHES ON CAOCAO

Han Meimei needs to make a new list on which the relationship between books and the categories is shown by indents. The rules are:

1) The n-th class category has an indent of  4×(n-1) spaces before it.
2) The book directly belongs to the n-th class category has an indent of  4×n spaces before it.
3) The categories and books which directly belong to a category X should be list below X in dictionary order. But all categories go before all books. 
4) All first class categories are also list by dictionary order.

For example, the book list above should be changed into the new list shown below:

ART
    HISTORY
        CHINESE HISTORY
            THREE KINDOM
                RESEARCHES ON CAOCAO
                RESEARCHES ON LIUBEI
            CHINESE MORDEN HISTORY
        JAPANESE HISTORY
            JAPANESE ACIENT HISTORY
MATH
    GRAPH THEORY

Please help Han Meimei to write a program to deal with her job.

输入

There are no more than 10 test cases.
Each case is a list of no more than 30 books, ending by a line of "0". 
The description of a book contains only uppercase letters, digits, ‘/‘ and spaces, and it‘s no more than 100 characters.
Please note that, a same book may be listed more than once in the original list, but in the new list, each book only can be listed once. If two books have the same name but belong to different categories, they are different books.

这题主要是考察坑爹点。

首先是用字典树解决的了。

我的做法比较复杂,因为一开始的时候没想到用map来离散那些字符串。

所以我的就是,在字典树中开多了个数组来保存字符串,

struct node {
  char has[30 + 2][100 + 2]; //用来保存同一级目录下是否的字符串
  int use;            //判断有多少个字符串了
  struct node * pNext[30 + 2]; //然后第i个字符串的下一个是谁,相当于离散化了。
} tree[10000 + 2];

坑爹

1:用"0"结束,那么你判断name[1] == ‘0‘就GG了,因为有可能是0ABC这样的数据。

2:目录和文件名是不同的,A/B  和 A  其中的A是不同的,因为是不同含义,第二个是文件名

3:相同的只算一次。

4:四个空格和一个\t不等价

还有就是一个很坑爹的地方,

就是样例那里了,为什么不是按字典序输出,而且有些比较长的目录优先输出。

这样的话,又要判断了,优先输出有孩子的那个。

我的代码看不懂的了,可以用来找样例吧,我给几组数据。

A
A
A
A/A
A/A/A
A/A/A
A/A/A/A/A
A/A/A/A/A/A
A
A/A/A
A/A/A/A/A
AA/A
0

A/B/C

A/B

0

A/B

A

0A

A

我这里要倒这排序这些字符串,因为要解决

A/B

A

先插入A/B

还有判断优先输出有儿子的,有就是有,不管有多少个。取值为1 or 0

dfs输出的时候,可以用cur表示再它前面已经输出了多少个,那么输出对应空格即可。

感觉我这个字典树用的还是比较6的,不过细节那么多,做了很久。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>

struct bookList {
    char name[100 + 20];
    bool operator < (const struct bookList & rhs) const {
        return strcmp(name + 1, rhs.name + 1) > 0;
    }
} book[300 + 2];
struct node {
    char has[30 + 2][100 + 2];
    int use;
    struct node * pNext[30 + 2];
} tree[10000 + 2];
struct TT {
    int id;
    int nextChild;
    bool operator < (const struct TT & rhs) const {
        if (nextChild != rhs.nextChild) return nextChild > rhs.nextChild;
        else return id > rhs.id;
    }
}FOR[1000 + 2][30 + 2];
int all;
int t;
struct node * create() {
    struct node * p = &tree[t++];
    p->use = 0;
    for (int i = 1; i <= 30; ++i) {
        memset(p->has[i], 0, sizeof p->has[i]);
        p->pNext[i] = NULL;
    }
    return p;
}
void insert(struct node **T, char str[], int lenstr) {
    struct node * p = *T;
    if (p == NULL) {
        *T = p = create();
    }
    str[lenstr + 1] = ‘/‘;
    char sub[222];
    int lensub = 0;
    for (int i = 1; i <= lenstr + 1; ++i) {
        if (str[i] == ‘/‘) {
            sub[lensub + 1] = ‘\0‘;
            bool flag = false;
            for (int j = 1; j <= p->use && i != lenstr + 1; ++j) {
                if (strcmp(sub + 1, p->has[j] + 1) == 0) {
                    p = p->pNext[j];
                    flag = true;
                    break;
                }
            }
            if (flag == false) {
                p->use++;
                strcpy(p->has[p->use] + 1, sub + 1);
                p->pNext[p->use] = create();
                p = p->pNext[p->use];
            }
            lensub = 0;
        } else sub[++lensub] = str[i];
    }
}
int liu;
char str1[111], str2[111];
void dfs(struct node *T, int cur, struct TT tosort[]) {
    if (T == NULL) return;
    struct node *p = T;
    for (int i = 1; i <= p->use; ++i) {
        tosort[i].id = i;
        tosort[i].nextChild = p->pNext[i]->use > 0;
    }
    sort(tosort + 1, tosort + 1 + p->use);
    for (int i = 1; i <= p->use; ++i) {
        for (int j = 1; j <= cur; ++j) {
            for (int k = 1; k <= 4; ++k) printf(" ");
        }
        printf("%s\n", p->has[tosort[i].id] + 1);
        dfs(p->pNext[tosort[i].id], cur + 1, FOR[++liu]);
    }
}
int f = 0;
void work() {
    while (gets(book[++all].name + 1) != NULL && strcmp(book[all].name + 1, "0") != 0) ;
    all--;
    sort(book + 1, book + 1 + all);
//    for (int i = 1; i <= all; ++i) {
//        printf("%s\n", book[i].name + 1);
//    }
//    printf("\n");
    struct node *T = NULL;
    memset(str1, 0, sizeof str1);
    memset(str2, 0, sizeof str2);
    strcpy(str2 + 1, book[1].name + 1);
    for (int i = 1; i <= all; ++i) {
//        printf("%s %s\n", str1 + 1, str2 + 1);
        if (strcmp(str1 + 1, str2 + 1) == 0) {
            strcpy(str1 + 1, str2 + 1);
            strcpy(str2 + 1, book[i + 1].name + 1);
            continue;
        }
        strcpy(str1 + 1, str2 + 1);
        strcpy(str2 + 1, book[i + 1].name + 1);
        insert(&T, book[i].name, strlen(book[i].name + 1));
    }
    printf("Case %d:\n", ++f);
    liu = -1;
    dfs(T, 0, FOR[++liu]);
}
int main() {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    while (gets(book[++all].name +1) != NULL && strcmp(book[all].name + 1, "0") != 0) {
        work();
//        printf("\n");
        all = 0;
        t = 0;
//        memset(tree, 0, sizeof tree);
//        memset(FOR, 0, sizeof FOR);
//        memset(book, 0, sizeof book);
    }
    return 0;
}

时间: 2024-08-09 11:51:57

hihoCoder 1383 : The Book List 北京网络赛的相关文章

2015北京网络赛A题The Cats&#39; Feeding Spots

题意:给你一百个点,找个以这些点为中心的最小的圆,使得这个圆恰好包含了n个点,而且这个圆的边界上并没有点 解题思路:暴力枚举每个点,求出每个点到其他点的距离,取第n大的点,判断一下. 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<iostream> 5 #include<memory.h> 6 using namespace std; 7 const i

2015北京网络赛 Couple Trees 倍增算法

2015北京网络赛 Couple Trees 题意:两棵树,求不同树上两个节点的最近公共祖先 思路:比赛时看过的队伍不是很多,没有仔细想.今天补题才发现有个 倍增算法,自己竟然不知道.  解法来自 qscqesze ,这个其实之前如果了解过倍增的话还是不是很难,不过这题的数据也不是很给力,极限数据理论上是过不了的.  其他解法有树链剖分?并不是很清楚.就这样水过了吧... 1 #include <iostream> 2 #include <cstdio> 3 #include &l

hihocoder1236(北京网络赛J):scores 分块+bitset

北京网络赛的题- -.当时没思路,听大神们说是分块+bitset,想了一下发现确实可做,就试了一下,T了好多次终于过了 题意: 初始有n个人,每个人有五种能力值,现在有q个查询,每次查询给五个数代表查询的五种能力值,输出有多少个人每种能力值都比查询的小 n和q都是50000,每种能力值最大也为50000 思路: 对于某一个大小的能力值,有哪些人的此项能力值比他小可以用一个50000的bitset表示.这样我们在查询的时候就可以拿到5个对应的bitset,对其进行and就可以得出最终的人数 这样每

2015北京网络赛 D-The Celebration of Rabbits 动归+FWT

2015北京网络赛 D-The Celebration of Rabbits 题意: 给定四个正整数n, m, L, R (1≤n,m,L,R≤1000). 设a为一个长度为2n+1的序列. 设f(x)为满足x≤ai≤m+x且ai的异或和为0 的序列a的个数. 求 ∑Rx=Lf(x)mod1000000007 思路:因为对于每一个第一次分配后的a序列对应唯一的x,所以我们就枚举x然后在求序列的个数.

HDU-4041-Eliminate Witches! (11年北京网络赛!!)

Eliminate Witches! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1124    Accepted Submission(s): 426 Problem Description Kaname Madoka is a Magical Girl(Mahou Shoujo/Puella Magi). The duty of

2015 北京网络赛 E Border Length hihoCoder 1231 树状数组 (2015-11-05 09:30)

#1231 : Border Length 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Garlic-Counting Chicken is a special species living around the Lake of Peking University. A Garlic-Counting Chicken always flies out from home in the morning, goes to some fixed points looki

hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题

题目大意: 每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数 因为强行要求在线查询,所以题目要求,每次当前给定的学生成绩都异或上一次的答案 先将学生按每一门成绩都排一次序 这里将学生分块成sqrt(n)的块数,然后在当前块中用bitset容器来记录含有学生的状态 这里可以记录状态的前缀和,因为比后面成绩好的,必然比前面的学生的成绩也好 查询的时候只要查到正好比他高的学生属于哪一块,这样只要访问sqrt(n

hihoCoder #1388 : Periodic Signal ( 2016 acm 北京网络赛 F题)

时间限制:5000ms 单点时限:5000ms 内存限制:256MB 描述 Profess X is an expert in signal processing. He has a device which can send a particular 1 second signal repeatedly. The signal is A0 ... An-1 under n Hz sampling. One day, the device fell on the ground accidenta

hihocoder 1582 : Territorial Dispute (计算几何)(2017 北京网络赛E)

题目链接 题意:给出n个点.用两种颜色来给每个点染色.问能否存在一种染色方式,使不同颜色的点不能被划分到一条直线的两侧. 题解:求个凸包(其实只考虑四个点就行.但因为有板子,所以感觉这样写更休闲一些.).如果不是所有点都在凸包上,那么把凸包上的点染成颜色1,内部的点染成颜色2:如果是所有点都在凸包上,且点数>3,那么将第一个和第三个点染成颜色1,其余点染成颜色2:否则,不存在满足要求的染色方式. 虽然很弱但是拿到一个一血还是非常开心的~ #include<bits/stdc++.h> u