1. 程式人生 > >《演算法競賽入門經典》一破損的鍵盤(又名:悲劇文字)(Broken Keyboard)

《演算法競賽入門經典》一破損的鍵盤(又名:悲劇文字)(Broken Keyboard)

問題描述:

       你有一個破損的鍵盤。鍵盤上所有的鍵都可以正常工作,但有時候Home鍵或者End鍵會自動按下。你並不知道鍵盤存在這一問題,而是專心打稿子,甚至連顯示器都沒開啟。當你開啟顯示器後,展現在你面前的是一段悲劇文字。你的任務是在開啟顯示器之前計算出這段悲劇文字。

       輸入包含多組資料。每組資料佔一行,包含不超過100000個字母、下劃線、字元“【”或者“】”。其中字元“【”表示Home鍵,“】”表示End鍵。輸入結束標誌為檔案結束符(EOF)。輸入檔案不超過5MB。對於每組資料,輸出一行,即螢幕上的悲劇文字。

樣例輸入:

This_is_a_[Beiju]_text

樣例輸出:

BeijuThis_is_a_text

分析:(資料結構一連結串列的簡單實現)

1.本題最簡單的想法就是直接開陣列儲存,再用pos儲存游標位置,但是由於陣列中插入元素操作的時間複雜度為O(n),當資料量過大時時間複雜度爆炸。

2.因此我們可以運用陣列模擬連結串列來儲存字元。建立一個next陣列來儲存輸出的順序,cur表示模擬當前游標的位置,last表示文字末端。

這道題我當時對著書上的程式碼看了半天,也用手模擬著跑過好幾次,感覺也是很玄乎Orz..

 話不多說,直接上程式碼

 1 #include <stdio.h>
 2
#include <string.h> 3 #define MAX 100005 4 char s[MAX]; 5 int next[MAX]; 6 int main() 7 { 8 while(scanf("%s",s+1)!=EOF) 9 { 10 int i,cur=0,last=0,len=strlen(s+1); 11 next[0]=0; 12 for(i=1;i<=len;i++) 13 { 14 char ch=s[i]; 15 if
(ch=='[') cur=0; 16 else if(ch==']') cur=last; 17 else 18 { 19 next[i]=next[cur]; //類似於 i->next=cur->next;cur->next=i; 20 next[cur]=i; 21 if(cur==last) last=i; 22 cur=i; 23 } 24 } 25 for(i=next[0];i!=0;i=next[i]) //類似於通過i=next[i]來訪問陣列 26 printf("%c",s[i]); 27 printf("\n"); 28 } 29 return 0; 30 31 }

還是很值得反覆去琢磨一下的。如果有dalao有更好的方法,或者有更清晰明確的理解,歡迎在文章下面評論一下。 Orz