Educational Codeforces Round 153 (Rated for Div. 2)

Educational Codeforces Round 153 (Rated for Div. 2)

 

A. Not a Substring

只有” ( ) () ()“这种情况无解,否则判断给出的序列是否有两个连续的相同括号,有则构造n个" ( ) () ()",否则构造n层嵌套括号

void solve(){
    string s;
    cin >> s;
    n = s.size();
    if(s == "()"){
        cout << "NO\n";
        return;
    }
    cout << "YES\n";
 
    bool f = false;
    for(int i = 0;i < n  -1;i++) if(s[i] == s[i+1]) f = true;
    if(f){
        for(int i = 1;i <= 2 * n;i++) {
            if(i & 1) cout << '(';
            else cout << ')';
        }
    }else{
        for(int i = 1;i <= n;i++) cout << '(';
        for(int i = 1;i <= n;i++) cout << ')';
    }
    cout << '\n';
}

 

B. Fancy Coins

先分别使用所有大面值和小面值的普通硬币,如果还不够则再先使用大面值花式硬币,若还不够要判断此时是否能收回之前使用的一元普通硬币从而只用再消耗一枚k元花式硬币,若不行最后再使用一元花式硬币

void solve(){
    cin >> m >> k >> a1 >> ak;
    int ans = 0;
    if(ak * k > m){
        m %= k;
        m = max(0ll, m - a1);
        cout << m << '\n';
        return;
    }
    m -= ak * k;
    if(m <= a1){
        cout << "0\n";
        return;
    }
    m -= a1;
 
    int ck = m / k;
    ans += ck;
    m -= ck * k;
 
    if(m && a1 + m >= k) ans++;
    else ans += m;
 
    cout << ans << '\n';
}

 

C. Game on Permutation

做P/N分析即可

对于Alice:

若一开始放在从第一个数开始递减的一段区间,都是必败的。

从这个区间后的第一个数开始往后推:递减区间后的第一个数只能被移动到必败态,所以该位置是必胜态,继续往后分析即可

  • 只能移动到必败态的是必胜态
  • 能移动到必胜态的是必败态
  • 不能移动的是必败态

往后递推时用一个树状数组记录前方是否有比当前的数小的必胜态即可

int w[N];
int lowbit(int x){
    return x & -x;
}
void addw(int x, int v){
    while(x <= n){
        w[x] += v;
        x += lowbit(x);
    }
}
int getw(int x){
    int ret = 0;
    while(x > 0){
        ret += w[x];
        x -= lowbit(x);
    }
    return ret;
}

void init(){
    for(int i = 1;i <= n;i++) w[i] = 0;
}

void solve(){
    cin >> n;
    init();
    for(int i = 1;i <= n;i++) cin >> a[i];

    int mn = a[1];
    int p = n + 1;
    for(int i = 2;i <= n;i++){
        if(a[i] > a[i-1]){
            p = i;
            break;
        }
        mn = min(a[i], mn);
    }

    int ans = 0;
    for(int i = p;i <= n;i++){
        if(getw(a[i]) == 0 && a[i] > mn) addw(a[i], 1), ans++;
        mn = min(mn, a[i]);
    }

    cout << ans << '\n';
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BowTen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值