[海豹海边爆]牛客21303

原题链接:登录—专业IT笔试面试备考平台_牛客网

解题思路:本题可以利用动态规划来解题。首先题目内删除的括号对,必须是紧邻的,即括号对之间删除时不能间隔任何字符。也就是说,如果决定删除一个中间有字符串的括号对,那么括号对内的所有括号都必须被删除后,外层的括号对才能删除。

也就是说,一旦决定开始删除左括号,则必须在遇到右括号时一起消除,直到之前的所有被删除的左括号对应上右括号,才能不选择删除。如果在删除左括号但没碰到右括号,而是碰到了另一个左括号,则后者也必须被删除,因为删除的括号对间不能有字符。此时就需要多找一个右括号了。

那么在没有未匹配到右括号的已经被删除左括号(在下文简称剩余删除左括号数)时,才可以选择保留这个字符。当这个字符和t字符串的下一个字符匹配时,s字符串的位置和t字符串的待匹配字符位置才可以一起向后推移一位。

当s字符串与t字符串的匹配位置都达到末尾,且没剩余删除左括号数为0的情况是可以达到的,才输出可能。

AC代码:

#include<bits/stdc++.h>
using namespace std;
string s,t;//题目原意 
long long ls,lt;//s字符串的长度与t字符串的长度 
bool dp[150][150][150];//dp用数组,记录当前是否匹配
//dp数组的第一维为s字符串位置,第二维是t字符串位置,第三维是当前已经消除了几个左括号但是还没有匹配到右括号 
int main(){
    dp[0][0][0]=1;//两个字符串都没开始匹配时,即空字符串,必然匹配 
    cin>>s>>t;
    ls=s.length();
    lt=t.length();
    s=' '+s;
    t=' '+t;
    for(int i=0;i<=ls;i++){
        for(int j=0;j<=lt;j++){
            for(int k=0;k<=ls;k++){
                if(dp[i][j][k]){//这种情况本身时可以达到的,才可以从这种情况推下一个情况 
                    if(k==0&&s[i+1]==t[j+1]) dp[i+1][j+1][0]=1;//如果此时匹配,且不存在只消除左括号还没消除对应右括号时才会继承
					//因为删除的括号一定为紧邻的,如果第三维不为0就开始匹配可能导致删除的左右括号间是有东西的
					//除非对应的左右括号间的括号对都在之前删除了才能删除 
                    if(s[i+1]=='(') dp[i+1][j][k+1]=1;//如果删除该左括号,则s字符串处理后的字符串,与t字符串已经比对的字符串依然匹配,因为这个左括号视作删除了 
                    else if(k) dp[i+1][j][k-1]=1;//如果此时k不为0,即有没有匹配上的左括号,以及此时为右括号,所以可以对应删除 
                }
            }
        }
    }
    if(dp[ls][lt][0]) cout<<"Possible";//只有在所有删除的括号都合法的成对删除,k才为0。而s字符串与t字符串也已经匹配完相同,答案才为可能。 
    else cout<<"Impossible";
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值