标签:push rmi false board scanf cas keyboard each getline
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 ?nished 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 ?nd 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-?le (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 }
标签:push rmi false board scanf cas keyboard each getline
原文地址:https://www.cnblogs.com/AlphaWA/p/9280974.html