1. 程式人生 > 實用技巧 >【NOIP2016模擬3】圖書列表

【NOIP2016模擬3】圖書列表

Description

Peking University Library的歷史和Peking University一樣長,它始建於1898年。截止到2015年,它包含大約11000千冊館藏圖書,其中8000千冊為紙質圖書,其餘為電子圖書。主席曾在1918~1919年間在該館任職,他的工資是8大洋/月,當時頂尖教授的工資是280大洋/月。
現在小G在館中擔任與主席曾經任職過的相同的職位。他的第一份工作是重新安排一些圖書。他得到了一張列表,每個表項具有以下格式:
CATEGORY1/CATEGORY 2/..../CATEGORY n/BOOKNAME
這表示圖書BOOKNAME位於目錄CATEGORY n下, 目錄CATEGORY n 位於目錄CATEGORY n-1下,目錄CATEGORY n-1位於目錄CATEGORY n-2下, 以此類推。也就是說,每個表項是由最後的一本圖書,以及該圖書所屬的若干目錄按照層級依次組成的。我們稱CATEGORY1為一級目錄,而CATEGORY 2為二級目錄,以此類推。例如:
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
小G認為這份列表很不容易閱讀和查詢,於是他決定按照以下規則製作一份新列表,用縮排來體現圖書與目錄之間的層級關係:

  1. n級目錄之前有4×(n-1)個空格的縮排。
  2. 直接隸屬於n級目錄的圖書前有4*n個空格的縮排。
  3. 直接隸屬於目錄X目錄與圖書按照字典序列在目錄X之後,但所有目錄位於所有圖書之前。
  4. 所有一級目錄按照字典序先後列出。
    例如,上面的列表轉化後將變為:
    ART
    HISTORY
    CHINESE HISTORY
    THREE KINDOM
    RESEARCHES ON CAOCAO
    RESEARCHES ON LIUBEI
    CHINESE MORDEN HISTORY
    JAPANESE HISTORY
    JAPANESE ACIENT HISTORY
    MATH
    GRAPH THEORY
    請寫一個程式幫助小G完成這項工作。

Input

輸入原列表,共包含不超過30本圖書,以一個數字0結尾。
每行列出一個表項,表項是一個由大寫字母、數字、“/”和空格構成的字串,長度不超過100。
一本圖書可能在列表中出現多次,但在轉化後的列表中,它應該只出現一次。但是若同名的圖書或目錄若在不同的目錄結構下,則認為他們是不相同的。換句話說,一個圖書或目錄由以它的名字為結尾的字首唯一確定。

Output

輸出新列表。本試題採用逐位元組比較,行末請勿輸出多餘空格,文末以恰好一個換行符結尾。

Sample Input

B/A
B/A
B/B
0

Sample Output

B
A
B

Hint

【資料規模與約定】
對於20%的資料,只有一級目錄。
對於另外20%的資料,沒有同名的圖書或目錄。
對於另外20%的資料,每本圖書僅出現一次。
對於100%的資料,參見輸入格式中給出的資料範圍,沒有其它特殊約定。


思路

  • 暴力
  • 學習字串相關函式
  • 排序時想清楚優先順序
  • len表示圖書深度(自己理解),註釋部分為排序後的結果

程式碼

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
struct fdfdfd{string c[105];int len;}a[35];
int n,maxlen,flag[35];
string keep[105];
bool cmp(fdfdfd x,fdfdfd y)
{
	for(int i=1;i<=max(x.len,y.len)+1;++i)
	{
                //此處優先順序
		if(x.len!=y.len)//len前字元完全相同,len不同時圖書在目錄後
		{
			if(x.len<y.len&&x.len==i) return 0;
			if(x.len>y.len&&y.len==i) return 1;
		}
		if(x.c[i].compare(y.c[i])>0) return 0;//比較len前字串按字典序
		if(x.c[i].compare(y.c[i])<0) return 1;
		if(x.len==y.len) {if(x.len==i) return 1;}//len前字元完全相同,len相同時字典序
	}
}
int main()
{
	for(int i=1;;++i,++n)
	{
		char temp=getchar();
		if(temp=='0') break;
		a[i].c[1]+=temp; a[i].len=1;
		for(int j=1;;)
		{
			temp=getchar();
			if(temp=='\n') break;
			if(temp=='/') ++a[i].len,++j,temp=getchar();
			a[i].c[j]+=temp;
		}
	}
	sort(a+1,a+n+1,cmp);
/*	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=a[i].len;++j) cout<<a[i].c[j]<<' ';
		cout<<endl;
	}
	cout<<"__________"<<endl;*/
	for(int i=1;i<=n;++i)
	{
		int num=0,k=a[i].len+1;
		for(int j=1;j<=a[i].len;++j,++num)
			if(a[i].c[j]!=keep[j]){k=j; break;}
		for(int j=k;j<=a[i].len;++j,++num)
		{
			keep[j]=a[i].c[j];
			for(int p=1;p<=num;++p) cout<<"    ";
			cout<<a[i].c[j]<<endl;
		}
	}
	return 0;
}