The 2015 ACM-ICPC Asia Beijing First Round Online Programming Co
L:如果光标左边还有字符,光标左移
R:如果光标右移还有字符,光标右移
S:切换模式(插入模式,复写模式),初始时默认为“插入模式”,然后每次遇到S都切换模式
B:如果光标左边有一个字符,删除
D:如果光标右边有一个字符,删除
C:复制,初始化为NOTHING,当C为NOTHING并且遇到C时,记录当前光标位置为复制起点,C变成start
当C为start遇到C时,记录当前光标位置为复制终点,把起点和终点之间的字符按照从左到右的顺序放进粘贴板,如果粘贴板内已有内容,就新的替换旧的;
如果复制起点和终点位置一样,则把粘贴板清空
V:把粘贴板内的字符粘贴到光标右边
特别地:
如果C处于start状态,则遇到L、R、D之外的字母都会打断复制状态,把C改为NOTHING状态
D:如果在C为start状态下遇到D,则删除此刻光标位置与复制起点之间的字母
复写模式:1.读入小写字母时会把光标右一个字母替换
2.粘贴时,假设粘贴板内k个字母,会把光标右边k个位置替换成粘贴板内容(即使光标右边的字母少于k个)
无论插入还是粘贴,所需要读取的密文字母数不能大于m,如果插入或粘贴会导致密文大于m,则不执行该操作
思路:用两个栈,一个栈保存光标左边内容,另一个栈保存光标右边内容,插入字母都往左边的栈插,用一个变量记录复制起点与终于的相对移动位置,如:记录起点为e = 0,
如果复制往左移则e--,右移则e++,最后处理粘贴板时,如果e>0则复制内容在右边的栈,e<0则在左边的栈,e=0则表示要情况粘贴板
明天就是中秋,最近也刚好上映谍中谍,别人都在说电影,而我在做“谍中谍”,队友现场就过了这题,而我赛后WA了n多次,随机测试数据才发现有个很小的细节,也难怪,代码长了照顾不来。
AC代码:
#include <stdio.h>
#include <stack>
#include <string.h>
#define maxn 10010
#define insert_mode 1
#define overwrite_mode 0
using namespace std;
stack<char> L;
stack<char> R;
char s[maxn], c[maxn];
bool copy1, status;
int m, end1, e, ok;
void L_fun(){
if(!L.empty()){
char tmp = L.top();
R.push(tmp);
L.pop();
if(copy1) e--;
}
}
void R_fun(){
if(!R.empty()){
char tmp = R.top();
L.push(tmp);
R.pop();
if(copy1) e++;
}
}
void S_fun(){
if(status == insert_mode) status = overwrite_mode;
else status = insert_mode;
}
void D_fun(){
if(copy1){
ok = e;
{
if(ok < 0)
while(ok!=0)
{
ok++;
R.pop();
}
else if(ok > 0)
while(ok!=0)
{
ok--;
L.pop();
}
}
}
else if(!R.empty()){
R.pop();
}
}
void B_fun(){
if(!L.empty())
L.pop();
}
void C_fun(){
if(copy1){
copy1 = false;
ok = e;
if(ok == 0) c[0] = '\0';
if(ok < 0)
{
int t = 0;
while(ok<0)
{
char tmp = R.top();
c[t++] = tmp;
R.pop();
ok++;
}
c[t] = '\0';
for(int i = strlen(c) - 1;i >= 0;i--) R.push(c[i]);
}
if(ok > 0)
{
int t = ok;
c[t--] = '\0';
while(ok>0)
{
char tmp = L.top();
c[t--] = tmp;
L.pop();
ok--;
}
for(int i = 0;i < strlen(c);i++) L.push(c[i]);
}
}
else{
copy1 = true;
e = 0;//复制开始
}
}
void V_fun(){
if(status&&(L.size()+R.size()+strlen(c)<=m)){
for(int i = 0;i < strlen(c);i++)
L.push(c[i]);
}
else if(!status&&L.size()+strlen(c)<=m){//!status
for(int i = 0;i < strlen(c);i++)
{
if(!R.empty())
R.pop();
L.push(c[i]);
}
}
}
void init(){
copy1 = false;
c[0] = '\0';
while(!L.empty()) L.pop();
while(!R.empty()) R.pop();
status = insert_mode;
}
int main()
{
int i, t;
scanf("%d", &t);
while(t--)
{
scanf("%d %s", &m, s);
end1 = strlen(s);
init();
for(i = 0;i < end1;i++)
{
if(s[i]>='a'&&s[i]<='z'){
if(!status&&!R.empty())
R.pop();
if(L.size()+R.size()+1<=m)
L.push(s[i]);
copy1 = false;
}
if(s[i] == 'L') L_fun();
if(s[i] == 'R') R_fun();
if(s[i] == 'S') S_fun();
if(s[i] == 'D') D_fun();
if(s[i] == 'B') B_fun();
if(s[i] == 'C') C_fun();
if(s[i] == 'V') V_fun();
if(s[i]!='L'&&s[i]!='R'&&s[i]!='C') copy1 = false;
}
if(L.empty()&&R.empty()) printf("NOTHING");
while(!L.empty()){
char tmp = L.top();
R.push(tmp);
L.pop();
}
while(!R.empty()){
char tmp = R.top();
printf("%c", tmp);
R.pop();
}
printf("\n");
}
}