牛客小白月赛87 D 小苯的IDE括号问题(hard)

原题链接: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;
}

  • 29
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
动态规划在解决牛客删除括号问题时,可以按照以下步骤进行: 1. 首先,我们需要理解题目的需求。题目要求我们删除括号,使得剩下的字符串满足以下条件:左括号和右括号的数量相等,且左括号的位置必须在右括号的前面。 2. 接下来,我们可以使用动态规划来解决这个问题。我们可以定义一个三维的dp数组,其中dp[q][w][e]表示考虑s前q个字符,t前w个字符,且s被删除部分左括号数减去右括号数为e时,是否可行(bool类型)。 3. 然后,我们可以从前向后遍历字符串s和t。在每一步中,我们可以考虑两种情况: a. 删除的左括号数目比右括号多:我们可以继续删除左括号,或者删除右括号。即dp[q][w][e] = dp[q-1][w][e+1]或dp[q-1][w][e-1]。 b. 删除的左括号数目与右括号数目相同:我们只能删除右括号。即dp[q][w][e] = dp[q-1][w-1][e-1]。 4. 最后,我们可以根据dp[len1][len2][0]的值来判断是否可行。其中len1和len2分别表示字符串s和t的长度。 综上所述,通过动态规划的思路,我们可以解决牛客删除括号问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [动态规划笔记](https://download.csdn.net/download/weixin_38617297/13751806)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [牛客_21303删括号_动态规划](https://blog.csdn.net/weixin_45619006/article/details/114650172)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值