AtCoder Regular Contest 175(A~B)

补题:A - Spoon Taking Problem

阅读理解就能劝退好多人,先看B题可能收益会更高。

N个人都是这么坐的,勺子标号也给你标好了。

如果 s[1]=L,那么1这个人就要拿左边的勺子,如果左边没有就拿右边的,右边也没有就无解。

s[1]=R,也同理

如果s[1]=?,那么代表这个人左手和右手由我们来决定。

如果第一个人拿了右边,那么接下来所有人都必须拿右边,否则一定无解。

那么考虑s[1]=?,如果有一开始拿的是右边,而且轮到?的这个人,只有右边这个勺子,那么这个人是左手和右手都没有关系,总方案就会*2

然后模拟所有情况。

注意给了p序列决定了拿勺子的顺序,所以第一个人 s[p[1]],不是s[1]

#include <bits/stdc++.h>
#define int long long
#define per(i,j,k) for(int (i)=(j);(i)<=(k);++(i))
#define rep(i,j,k) for(int (i)=(j);(i)>=(k);--(i))
#define debug(a) cout<<#a<<"="<<a<<endl
#define all(x) x.begin(),x.end()
#define EX exit(0)
#define fr first
#define se second
#define endl '\n'
using namespace std;
using ll=long long;
const int N=2e5+5,MOD=998244353;

int n,p[N];
string s;

int doL(){
    int ans=1;

    bool vis[n+5];
    per(i,0,n+1)vis[i]=false;
    vis[0]=vis[n+1]=true;
    vis[p[1]]=true;

    per(i,2,n){
        //接下来都拿左手
        int l=p[i],r=p[i]+1;
        if(r==n+1)r=1;

        if(vis[l] and vis[r]){//没勺子拿了
            return 0;
        }else
        if(!vis[l] and !vis[r]){//两个勺子都还在
            if(s[l]=='R'){//拿右无解
                return 0;
            }//剩下情况都拿左手
            vis[l]=true;
        }else
        if(!vis[l]){//只有左勺子
            vis[l]=true;
            if(s[l]=='?'){
                ans*=2;
                ans%=MOD;
            }
        }else{//只有右勺子
            return 0;
        }
    }

    return ans;
}

int doR(){
    int ans=1;

    bool vis[n+5];
    per(i,0,n+1)vis[i]=false;
    vis[0]=vis[n+1]=true;
    if(p[1]+1==n+1)vis[1]=true;
    else vis[p[1]+1]=true;

    per(i,2,n){
        //接下来都拿右手
        int l=p[i],r=p[i]+1;
        if(r==n+1)r=1;

        if(vis[l] and vis[r]){//没勺子拿了
            return 0;
        }else
        if(!vis[l] and !vis[r]){//两个勺子都还在
            if(s[l]=='L'){//拿左无解
                return 0;
            }//剩下情况都拿右手
            vis[r]=true;
        }else
        if(!vis[r]){//只有右勺子
            vis[r]=true;
            if(s[l]=='?'){
                ans*=2;
                ans%=MOD;
            }
        }else{//只有左勺子
            return 0;
        }
    }

    return ans;
}

void solve(){
    cin>>n;
    per(i,1,n)cin>>p[i];
    cin>>s;
    s="0"+s;

    int ans;
    if(s[p[1]]=='L')ans=doL();
    else if(s[p[1]]=='R')ans=doR();
    else ans=doL()+doR();

    cout<<ans%MOD<<endl;
}

signed main(){
    ios::sync_with_stdio(false),cin.tie(nullptr);
    int t=1;
    while(t--)solve();
    return 0;
}

B - Parenthesis Arrangement

给你一个括号序列S,你可以进行两个操作:

1、交换 s[i],s[j]    花费 A

2、修改 s[i] 成为 '(' 或者 ')'     花费B

输出最少的花费,使得括号序列S成为合法的括号序列(每一个左括号都对应一个右括号)

首先,已经合法的括号就不需要修改了,这样的操作是多余的。

遍历括号序列,进栈,如果遇到栈顶是 '(',当前是 ')',那就弹出栈顶,否则当前入栈(去除合法括号)

然后就会剩下 ①(((((  或者 ②))))))  或者 ③))(((( 这三种情况。

显然①和②只能修改一半使序列合法。

③交换一次相当于修改两个位置。如果 a<=2*b,我们一定要先执行交换操作。

模拟一下若有 ))((((,交换一次 ()(((),显然一次交换产生了两对合法的,而不是一对。

交换完毕之后如果还有剩下的,((((,那么只需要将一半翻转。

如果a>2*b,那么我们只能翻转。

)))(((,左半边翻转一半,右半边翻转一半,如果是奇数还剩下两个括号 )(,那么还需要再翻两遍。

#include <bits/stdc++.h>
#define int long long
#define per(i,j,k) for(int (i)=(j);(i)<=(k);++(i))
#define rep(i,j,k) for(int (i)=(j);(i)>=(k);--(i))
#define debug(a) cout<<#a<<"="<<a<<endl
#define all(x) x.begin(),x.end()
#define EX exit(0)
#define fr first
#define se second
#define endl '\n'
using namespace std;
using ll=long long;

//交换 i,j 花费 A
//把 i 换成 (或者) 花费B

//最少花费,让S变成合法的括号序列


void solve(){
    int n,a,b;
    cin>>n>>a>>b;
    string s;
    cin>>s;

    stack<char>sta,sta1;
    sta.push(s[0]);
    per(i,1,s.length()-1){
        if(sta.size() and sta.top()=='(' and s[i]==')'){
            sta.pop();
        }else{
            sta.push(s[i]);
        }
    }

    int c9=0,c0=0;
    while(sta.size()){
        if(sta.top()=='(')c9++;
        else c0++;
        sta1.push(sta.top());
        sta.pop();
    }

    int ans=0;
    if(c9==0 or c0==0){
        ans=(c9+c0)/2*b;
    }else{
        //  )))(((((

        if(a<=2*b){
            ans=(min(c0,c9)+1)/2*a+(max(c0,c9)-min(c0,c9))/2*b;
        }else{//全部修改
            if(c0&1){
                ans=(c0/2+c9/2+2)*b;
                // )(
            }else{//偶数
                ans=(c0/2+c9/2)*b;
            }
        }
    }

    cout<<ans<<endl;
}

signed main(){
    ios::sync_with_stdio(false),cin.tie(nullptr);
    int t=1;
    while(t--)solve();
    return 0;
}

"missing right parenthesis"是Oracle数据库错误消息之一,表示在查询语句或存储过程中缺少右括号。这可能是由于在语句中的某个地方忘记了闭合括号导致的语法错误。这种错误通常由于括号未匹配或嵌套不正确引起。 引用中提到了一些与Oracle数据库相关的错误消息,包括"missing right parenthesis"。该错误消息在语法错误时会出现,比如在查询语句或存储过程中缺少右括号。 引用中的示例代码提示了一个可能导致"missing right parenthesis"错误的情况。在将系统时间格式转换并与数据库字段进行比较时,如果忘记闭合括号,就会出现这个错误。 要解决这个问题,您需要仔细检查查询语句或存储过程中的括号使用情况,确保每个左括号都有一个相应的右括号进行闭合。检查您的代码中的每个括号,确保它们正确匹配并嵌套正确。另外,还要确保您在使用括号时遵循正确的语法规则。 如果您仍然遇到困难,可以将相关代码片段提供给数据库管理员或开发人员,以便他们可以更详细地分析并解决问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SQL21日自学通](https://download.youkuaiyun.com/download/mao_zh/8277811)[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_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [关于ORA-00907: missing right parenthesis问题整理](https://blog.youkuaiyun.com/weixin_31960565/article/details/116466386)[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_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值