1. 程式人生 > >HihoCoder-1559 合併子目錄(純模擬)

HihoCoder-1559 合併子目錄(純模擬)

題意

輸入 n 個檔案的絕對路徑,如果一個名為 x x 的目錄下只有一個

y y 的資料夾,則將這兩層資料夾壓縮成一個名為 x x y y 的資料夾。求壓縮後這
" role="presentation" style="position: relative;"> n 個檔案的絕對路徑。
1 n 10000

1 n 個檔案的絕對路徑 500000

思路

對於檔案樹的問題,比較令人頭大的是不同父目錄下檔名相同的檔案,所以在判重時需要在同一父節點下,於是將邊集 v e c t o r m a p 合在一起,開一個 m a p 的邊集陣列 s o n ,其中 s o n u u 的子檔案的 s t r i n g 和其對映的 i n t
對於資料夾的 “ / ” 符號,通常化成“ ”直接用 i s t r i n g s t r e a m 讀入最為方便。

程式碼

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<map>
#define FOR(i,x,y) for(int i=(x);i<=(y);i++)
#define DOR(i,x,y) for(int i=(x);i>=(y);i--)
#define M 500003
#define N 10003
typedef long long LL;
using namespace std;
map<string,int>son[M];
string str[N],tmp;
int n,ID;

int main()
{
    scanf("%d",&n);
    FOR(i,1,n)
    {
        int u=0;
        cin>>str[i];
        FOR(j,0,(int)str[i].size()-1)if(str[i][j]=='/')str[i][j]=' ';
        istringstream sin(str[i]);
        while(sin>>tmp)
        {
            if(son[u].find(tmp)==son[u].end())son[u][tmp]=++ID;
            u=son[u][tmp];
        }
    }
    FOR(i,1,n)
    {
        string res="";
        int u=0;
        istringstream sin(str[i]);
        while(sin>>tmp)
        {
            if(son[u].size()==1&&u)res+='-';
            else res+='/';
            res+=tmp; 
            u=son[u][tmp];
        }
        DOR(j,(int)res.size()-1,0)
        {
            if(res[j]=='/')break;
            else if(res[j]=='-')
            {
                res[j]='/';
                break;
            }
        }
        cout<<res<<endl;
    }
    return 0;
}