You’re typing a long text with a broken keyboard. Well it’s not so badly broken. The only problem with the keyboard is that sometimes the “home” key or the “end” key gets automatically pressed (internally). You’re not aware of this issue, since you’re focusing on the text and did not even turn on the monitor! After you finished typing, you can see a text on the screen (if you turn on the monitor). In Chinese, we can call it Beiju. Your task is to find the Beiju text.
Input
There are several test cases. Each test case is a single line containing at least one and at most 100,000 letters, underscores and two special characters ‘[’ and ‘]’. ‘[’ means the “Home” key is pressed internally, and ‘]’ means the “End” key is pressed internally. The input is terminated by end-of-file (EOF).
Output
For each case, print the Beiju text on the screen.
Sample Input
This_is_a_[Beiju]_text
[[]][][]Happy_Birthday_to_Tsinghua_University
Sample Output
BeijuThis_is_a__text
Happy_Birthday_to_Tsinghua_University
概譯:我們在用鍵盤輸入字符串,如果出現' [ '光標就跳到最前面,如果出現' ] '就跳到最后面,給出輸入時的字符串輸出實際得到的字符串,詳見樣例。
思路:水題輕噴……模擬,鏈表插入,可以用數組實現模擬鏈表。我模擬鏈表不太熟,第一次是用STL模擬的。可以用一個雙端隊列deque儲存最終結果,遇到一個' [ '就把后面的字符放在stack里,再遇到' [ '或' ] '時把stack里的字符放在deque的front里。PS:可能WA的數據:abc[123[456[ef
STL比較慢,100msAC
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int main() 5 { 6 string s; 7 while(getline(cin,s)) 8 { 9 s+=']'; 10 deque<char>dq; 11 stack<char>st; 12 bool state=false; 13 14 for (int i = 0; s[i]; ++i) 15 { 16 if (s[i]=='[') state=true; 17 else if (s[i]==']') state=false; 18 19 if(state) 20 { 21 if(s[i]!='[') 22 st.push(s[i]); 23 else 24 while(!st.empty()) 25 { 26 dq.push_front(st.top()); 27 st.pop(); 28 } 29 } 30 else 31 { 32 if(s[i]!=']') 33 dq.push_back(s[i]); 34 while(!st.empty()) 35 { 36 dq.push_front(st.top()); 37 st.pop(); 38 } 39 } 40 } 41 42 while(!dq.empty()) 43 { 44 printf("%c",dq.front()); 45 dq.pop_front(); 46 } 47 printf("\n"); 48 } 49 return 0; 50 }
模擬鏈表是用一個next數組代替鏈表中的next指針,比如第一個字符s[1]的下一個是s[2],則next[1]=2。思想上和鏈表是一樣的。另外眾所周知,鏈表的題常常會把第0個作為不儲存數據的輔助頭結點,第一個下標才開始儲存數據。
標程的思路是設置一個光標cur,但這個cur不是當前遍歷到的位置i,而代表着位置i的字符應該插入在cur的右側。期間cur有時會跳至左端即cur=0;有時要回到右端,所以還要開一個last變量保存最右端的下標,使cur=last跳回右端。
代碼更精簡,30ms,如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define maxl 100005 4 5 int main() 6 { 7 char s[maxl]; 8 while(~scanf("%s",s+1)) 9 { 10 int Next[maxl]={0}; 11 int cur=0,last=0; 12 13 for (int i = 1; s[i]; ++i) 14 { 15 if(s[i]=='[') cur=0; 16 else if(s[i]==']') cur=last; 17 else 18 { 19 //鏈表插入操作 20 Next[i]=Next[cur]; 21 Next[cur]=i; 22 //last的更新 23 if(cur==last) last=i; 24 //cur的更新 25 cur=i; 26 } 27 } 28 29 for (int i = Next[0]; i != 0; i = Next[i]) 30 if (s[i]!='['&&s[i]!=']') 31 printf("%c",s[i]); 32 printf("\n"); 33 } 34 return 0; 35 }