CERC2017 H-Hidden Hierarchy【模拟+dfs】

题目描述

You are working on the user interface for a simple text-based file explorer. One of your tasks is to build a navigation pane displaying the directory hierarchy. As usual, the filesystem consists of directories which may contain files and other directories, which may, in turn, again contain files and other directories etc. Hence, the directories form a hierarchical tree structure. The top-most directory in the hierarchy is called the root directory. If directory d directly contains directory e we will say that d is the parent directory of e while e is a subdirectory od d. Each file has a size expressed in bytes. The directory size is simply the total size of all files directly or indirectly contained inside that directory. All files and all directories except the root directory have a name — a string that always starts with a letter and consists of only lowercase letters and “.” (dot) characters. All items (files and directories) directly inside the same parent directory must have unique names. Each item (file and directory) can be uniquely described by its path — a string built according to the following rules: • Path of the root directory is simply “/” (forward slash). • For a directory d, its path is obtained by concatenating the directory names top to bottom along the hierarchy from the root directory to d, preceding each name with the “/” character and placing another “/” character at the end of the path. • For a file f , its path is the concatenation of the parent directory path and the name of file f . We display the directory hierarchy by printing the root directory. We print a directory d by outputting a line of the form “md pd sd” where pd and sd are the path and size of directory d respectively, while md is its expansion marker explained shortly. If d contains other directories we must choose either to collapse it or to expand it. If we choose to expand d we print (using the same rules) all of its subdirectories in lexicographical order by name. If we choose to collapse directory d, we simply ignore its contents. The expansion marker md is a single blank character when d does not have any subdirectories, “+” (plus) character when we choose to collapse d or a “-” (minus) character when we choose expand d. Given a list of files in the filesystem and a threshold integer t, display the directory hierarchy ensuring that each directory of size at least t is printed. Additionally, the total number of directories printed should be minimal. Assume there are no empty directories in the filesystem — the entire hierarchy can be deduced from the provided file paths. Note that the root directory has to be printed regardless of its size. Also note that a directory of size at least t only has to be printed, but not necessarily expanded.

Input

The first line contains an integer n (1 ≤ n ≤ 1 000) — the number of files. Each of the following n lines contains a string f and an integer s (1 ≤ s ≤ 106 ) — the path and the size of a single file. Each path is at most 100 characters long and is a valid file path according to the rules above. All paths will be different. The following line contains an integer t (1 ≤ t ≤ 109 ) — the threshold directory size

Output

Output the minimal display of the filesystem hierarchy for the given threshold as described above.

Sample Input 1

9
/sys/kernel/notes 100
/cerc/problems/a/testdata/in 1000000
/cerc/problems/a/testdata/out 8
/cerc/problems/a/luka.cc 500
/cerc/problems/a/zuza.cc 5000
/cerc/problems/b/testdata/in 15
/cerc/problems/b/testdata/out 4
/cerc/problems/b/kale.cc 100
/cerc/documents/rules.pdf 4000
10000
 

Sample Output 1

- / 1009727
- /cerc/ 1009627
/cerc/documents/ 4000
- /cerc/problems/ 1005627
- /cerc/problems/a/ 1005508
/cerc/problems/a/testdata/ 1000008
+ /cerc/problems/b/ 119
+ /sys/ 100

Sample Input 2

8
/b/test/in.a 100
/b/test/in.b 1
/c/test/in.a 100
/c/test/in.b 1
/c/test/pic/in.a.svg 10
/c/test/pic/in.b.svg 10
/a/test/in.a 99
/a/test/in.b 1
101

Sample Output 2

- / 322
+ /a/ 100
- /b/ 101
/b/test/ 101
- /c/ 121
+ /c/test/ 121

Sample Input 2

2
/a/a/a 100
/b.txt 99
200

Sample Output 2

+ / 199

题意

题目很长很长很长……但就是一个模拟题!!

题意就是 每行有一个文件的路径和文件的大小,再给你一个t,从字典序小的文件夹开始打开

①如果当前文件夹下没有文件夹输出“(空格) 当前文件夹路径 大小”,结束

②如果有大小>=t的文件夹输出“- 当前文件夹路径 大小”,然后进入该文件夹,继续①

③如果没有大小>=t的文件夹输出“+ 当前文件夹路径 大小”,结束

思路

读懂题意后就容易多了,因为是要字典序小的,我们使用set(可以自动排序),map标记路径,每输入一个路径,查找‘/’,然后用map标记这个路径,在查找到最后一个‘/’时,把文件大小赋给文件夹。

然后dfs得到所有文件夹中大小

再dfs输出答案

代码

#include<iostream>
#include<cstdio>
#include<map>
#include<set>
#include<cstring>
using namespace std;

const int Max = 100005;
struct file{
    string name;
    set<string> v;
    long long sz;
};
file f[Max];
map<string, int> mp;

long long dfs1(int s)
{
    if(f[s].v.size() == 0)
    {
        //cout<<f[s].name<<" "<<f[s].sz<<endl;
        return f[s].sz;
    }

    set<string>::iterator itr;
    long long temp = 0;
    for(itr = f[s].v.begin(); itr != f[s].v.end(); itr++)
    {
        temp += dfs1(mp[*itr]);
    }
    f[s].sz += temp;
    //cout<<f[s].name<<" "<<f[s].sz<<endl;
    return f[s].sz;
}

void dfs2(int s, int t)
{
    if(f[s].v.size()==0)//没有文件夹
    {
        printf("  %s %lld\n", f[s].name.c_str(), f[s].sz);
        return;
    }
    set<string>::iterator itr;
    bool flag = false;
    for(itr = f[s].v.begin(); itr!=f[s].v.end(); itr++)
    {
        if(f[mp[*itr]].sz>=t)
        {
            flag = true;
            break;
        }
    }
    if(flag)//有大于t的文件夹
    {
        printf("- %s %lld\n", f[s].name.c_str(), f[s].sz);
        for(itr = f[s].v.begin(); itr!=f[s].v.end(); itr++)
        {
            dfs2(mp[*itr], t);
        }
    }
    else//没有大于t的文件夹
    {
        printf("+ %s %lld\n", f[s].name.c_str(), f[s].sz);
    }
}
int main()
{
    char s[105];
    int t,n,cnt = 1;
    scanf("%d", &n);
    mp["/"] = 0;
    f[0].name = "/";
    for(int i = 0; i < n; i++)
    {
        cin >> s >> t;
        int st = 1;
        string pre = "/";
        for(int j = 1; j < strlen(s); j++)
        {
            if(s[j] == '/')
            {
                char c = s[j+1];
                s[j+1] = '\0';//直接得到'/'前的路径
                if(mp.find(s) == mp.end())
                {
                    mp[s] = cnt;
                    f[cnt].name = s;
                    cnt++;
                }
                f[mp[pre]].v.insert(s);//set自动排序
                pre = s;
                s[j+1] = c;
            }
        }
        f[mp[pre]].sz += t;
    }
    dfs1(0);
    scanf("%d", &t);
    dfs2(0,t);
    return 0;
}

如有错误请指明~   ฅ●ω●ฅ

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值