原题链接:D-小苯的IDE括号问题(hard)
题目大意:给定一个长度为n的字符串,字符串由(,)和I构成,m组询问,如果输入backspace,如果I左右是(和)就一起删除,如果是只有(就只删除左边。如果是delete就删除右边,如果右边存在。如果输入<-就把I向左移动,如果是->就把I向右移动。
思路:可以观察到每次操作都与I有关,并且题目里面涉及大量的删改,我的思路和题解不一样,是用数组来记录字符,然后用数组来模拟链表,这样可以快速的删除I左右的元素和移动I。官方的思路是用栈来存在I左边和右边的字符串,然后根据条件来操作,为了方便输出,栈可以用vector来模拟。
我的思路代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
const int N=1e6+10,mod=10007;
char p[N];
ll l[N],r[N];
int main()
{ios::sync_with_stdio(NULL);cin.tie(0),cout.tie(0);ll n,m;cin>>n>>m;ll cnt=0;for(int i=1;i<=n;i++){cin>>p[i];l[i]=i-1;r[i]=i+1;if(p[i]=='I')cnt=i;}r[0]=1;l[n+1]=n;while(m--){if(r[0]>n)break;string s;cin>>s;if(s=="backspace"){ll a=l[cnt],b=cnt,c=r[cnt];if(a==0)continue;else if(c==n+1){ll x=l[a];r[x]=b,l[b]=x;}else{if(p[a]=='('&&p[c]==')'){ll x=l[a],y=r[c];r[x]=b;l[b]=x;r[b]=y;l[y]=b;}else{ll x=l[a];r[x]=b;l[b]=x;}}}else if(s=="delete"){ll a=l[cnt],b=cnt,c=r[cnt];if(c==n+1)continue;else{ll x=r[c];l[x]=b;r[b]=x;}}else if(s=="<-"){ll a=l[cnt],b=cnt,c=r[cnt];if(a==0)continue;ll x=l[a];l[c]=a;r[a]=c;l[b]=x;r[b]=a;r[x]=b;l[a]=b;}if(s=="->"){ll a=l[cnt],b=cnt,c=r[cnt];if(c==n+1)continue;ll x=r[c];r[a]=c;l[c]=a;l[b]=c;r[b]=x;r[c]=b;l[x]=b;}}for(int i=r[0];i<=n;i=r[i]){cout<<p[i];}cout<<endl;return 0;
}
官方思路代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
const int N=1e6+10,mod=10007;
char p[N];
int main()
{ios::sync_with_stdio(NULL);cin.tie(0),cout.tie(0);ll n,m;cin>>n>>m;ll cnt=0;for(int i=1;i<=n;i++){cin>>p[i];if(p[i]=='I')cnt=i;}vector<char> a,b;for(int i=1;i<cnt;i++)a.push_back(p[i]);//exit(0);for(int i=n;i>cnt;i--)b.push_back(p[i]);while(m--){string s;cin>>s;if(s=="backspace"){if(a.size()){if(b.size()&&b[b.size()-1]==')'&&a[a.size()-1]=='('){b.pop_back();}a.pop_back();}}if(s=="delete"){if(b.size()){b.pop_back();}}if(s=="<-"){if(a.size()){b.push_back(a[a.size()-1]);a.pop_back();}}if(s=="->"){if(b.size()){a.push_back(b[b.size()-1]);b.pop_back();}}}for(int i=0;i<a.size();i++){cout<<a[i];}cout<<'I';for(int i=b.size()-1;i>=0;i--){cout<<b[i];}return 0;
}