Codeforces Round 908 (Div. 2)

Codeforces Round 908 (Div. 2)

 

A. Secret Sport

题目保证s一定是合法序列,所以最后一场获胜的人使游戏结束,他就是winner

 

B. Two Out of Three

判断是否有两组及以上相同数即可,然后任意选两种情况赋值

 

C. Anonymous Informant

根据题目反向模拟,即对于 b i b_i bi,若 b i b_i bi向右滑动 b i b_i bi位后的下标正好等于 b i b_i bi,则b可经过一次变换得来。仔细观察可以发现只有 b n b_n bn可能会满足 “ b i b_i bi向右滑动 b i b_i bi位后的下标正好等于 b i b_i bi”,所以可以求出当前b最多可逆向滑动多少次(或者无限次),与k比较即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define endl '\n'
#define all(x) (x).begin(), (x).end()
const int N = 2e5 + 10;
int n, k; 

void solve(){
    cin >> n >> k;
    vector<int>a(n);
    vector<int>vis(n);
    for(int i = 0;i < n;i++) cin >> a[i];
    int cnt = 0;
    int p = n - 1;
    while(1){
        if(a[p] > n) break;
        if(vis[p]){
            cout << "Yes\n";
            return;
        }
        vis[p] = 1;
        p -= a[p];
        if(p < 0) p += n;
        cnt++;
    }
    cout << (cnt >= k ? "Yes\n" : "No\n");
}

signed main(){

    IO;
    int t = 1;
    cin >> t;
    while(t--) solve();

    return 0;
}

 

D. Neutral Tonality

a中已存在的逆序对数无法减小,所以对于每个 b i b_i bi只要将它放在第一个小于等于 b i b_i bi a i a_i ai前面就不会使逆序对数增加,没有小于 b i b_i bi的数就放在最后。但是直接查找每个小于 b i b_i bi a i a_i ai较难,并且b数组可重排,所以可以将b排序,对于每个 a i a_i ai二分查找第一个大于等于它的 b i b_i bi,将这个 b i b_i bi b i b_i bi后面的元素都放到 a i a_i ai前面

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define endl '\n'
#define all(x) (x).begin(), (x).end()
const int N = 2e5 + 10;
int n, m; 

void solve(){
    cin >> n >> m;
    vector<int>a(n), b(m);
    int mn = 1e10;
    for(auto& e : a) cin >> e, mn = min(mn, e);
    for(auto& e : b) cin >> e;
    sort(all(b));
    int len = m;
    bool f = true;
    for(int i = 0;i < n;i++){
        int p = lower_bound(b.begin(), b.begin() + len, a[i]) - b.begin();
        for(int j = len - 1;j >= p;j--) cout << b[j] << ' ';
        len = p;
        cout << a[i] << ' ';
    }
    for(int i = len - 1;i >= 0;i--) cout << b[i] << ' ';
    cout << endl;
}

signed main(){

    IO;
    int t = 1;
    cin >> t;
    while(t--) solve();

    return 0;
}

 

E. Freedom of Choice

求出X的最大和最小大小R,L,若(R-L+1)> 所有a种数,直接输出0

否则(R-L+1)<= 1e5,直接枚举X的每种可能大小len,假设先把所有数都取走,再去每个包含len这种数的set中查看可以少拿多少个len这种书,求出最终拿的len的个数,对每种情况取min即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define endl '\n'
#define all(x) (x).begin(), (x).end()
const int N = 1e5 + 10;
const int WIN = 0;
const int DRAW = 1;
const int LOSE = 2;
int m; 

void solve(){
    cin >> m;
    vector<int>n(m);
    vector<int>r(m);
    vector<int>l(m);
    vector<int>sum(m);
    vector<vector<int>>a(m);
    vector<vector<int>>c(m);
    map<int,int>cnt;
    map<int,vector<int>>stid;
    int L = 0, R = 0;
    for(int i = 0;i < m;i++){
        cin >> n[i] >> l[i] >> r[i];
        L += l[i];
        R += r[i];
        a[i].resize(n[i]);
        c[i].resize(n[i]);
        for(auto& e : a[i]) cin >> e, stid[e].push_back(i);
        for(int j = 0;j < n[i];j++){
            cin >> c[i][j];
            sum[i] += c[i][j];
            cnt[a[i][j]] += c[i][j];
        }
    }

    if(R - L + 1 > cnt.size()) {
        cout << "0\n";
        return;
    }

    int ans = 1e18;
    for(int len = L;len <= R;len++){
        if(!cnt[len]){
            cout << "0\n";
            return;
        }
        int tmp = cnt[len];
        int D = R - len;
        for(auto id : stid[len]){
            int p = lower_bound(all(a[id]), len) - a[id].begin();
            int d = sum[id] - r[id] + (r[id] - max(l[id], r[id] - D));
            int dd = min(d, c[id][p]);
            tmp -= dd;
            dd -= sum[id] - r[id];
            D -= dd;
        }
        ans = min(ans, tmp);
    }

    cout << ans << endl;
}

signed main(){

    IO;
    int t = 1;
    cin >> t;
    while(t--) solve();

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

BowTen

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

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

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

打赏作者

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

抵扣说明:

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

余额充值