Codeforces Round 897 (Div. 2)更新ing

A. green_gold_dog, array and permutation

题意
给你一个长度为\(n\)数组\(a\),需要构造出一个\(b\)数组,\(b\)数组是一个\(1-n\)的排列,对应得到\(a\)数组与\(b\)数组的每个位置对应的差构成\(c\)数组,\(c_i = a_i - b_i\)我们需要使得\(c\)数组元素种类更多,需要输出\(b\)数组的方案。
线索

提示1

假设\(a = [1, 2, 3, 4, 5]\),你会怎么构造\(b\)数组

提示2

假设\(a\)数组是有序的,那么我们\(b\)数组是不是逆序放置,使得元素差值最大化。

代码

点击查看代码
#define rep(i, a, b) for(int i = a;i <= b; ++i)
const int N = 2e5 + 10;
struct node {
    int x, id;
    bool operator < (const node& rhs) const {
        return x > rhs.x;
    }
}a[N];
int ans[N];
void solve() {
    int n;
    cin >> n;
    rep(i, 1, n) {
        cin >> a[i].x;
        a[i].id = i;
    }
    sort(a + 1, a + 1 + n);
    int idx = 0;
    rep(i, 1, n) {
        ans[a[i].id] = ++idx;
    }
    rep(i, 1, n) cout << ans[i] << " \n"[i == n];
}

B. XOR Palindromes

题意
给你一个长度为\(n\)的只有01组成的串\(s\),我们可以构造出一个新的长度的为\(n\)的串,也是只包含01,我们对位异或得到新串\(c\)\(c\)串必须是一个回文串,\(b\)串有很多种可能,含有\(1\)的个数不一定相同,我们需要输出可能会含有多少个1,方案打印为一个01串,第\(i\)为是1,就代表含有出现\(i\)个1的\(b\)串构造方案。
线索

提示1

统计需要最少需要使用几个1可以构造出回文串。

提示2

分奇数偶数讨论,如何添加1的个数,使得\(b\)串依旧是一个合法的构造方案

代码

点击查看代码
void solve() {
    int n;
    string s;
    cin >> n >> s;
    int cnt = 0, ok = 0;
    vector<int> vis(n + 1, 0);
    s = " " + s;
    rep(i, 1, n / 2) {
        if(s[i] != s[n - i + 1]) ++cnt;
        else ok++;
    }
    if(n & 1) vis[cnt + 1] = 1;
    vis[cnt] = 1;
    while(ok > 0) {
        cnt += 2;
        vis[cnt] = 1;
        if(n & 1) vis[cnt + 1] = 1;
        ok--;
    }
    rep(i, 0, n) cout << vis[i];
    cout << "\n";
}

C. Salyg1n and the MEX Game

题意
初始有一个长度为\(n\)的数组,a玩家和b玩家轮流玩游戏,a执行的操作是插入一个数\(x\),且插入的数数组中不能含有,b执行的操作是从数组中删除一个数,且删除的数需要严格小于a刚插入的数\(x\)。a玩家需要达成的目的是整个数组mex最大,b玩家需要达成的目的是mex最小,现在你来扮演a玩家,给出每次需要插入的数字,b玩家由测评机提供交互,给出每次删除的数,-1表示游戏无法进行。
线索

提示1 既然是最佳策略,你会怎么扩大mex的值,当然是把没有出现的最小值插入,是的mex增加一个1。

假设\(a = [1, 2, 3, 4, 5]\),你会怎么构造\(b\)数组

提示2

对手删除哪个数,我们就添加哪个数一直保持优势。(a玩家的先手优势有点巨大,这个题太bug

代码

点击查看代码
void solve() {
    int n, x;
    cin >> n;
    set<int> s;
    vector<int> a(n + 1);
    rep(i, 0, n) s.insert(i);
    rep(i, 1, n) {
        cin >> a[i];
        s.erase(a[i]);
    }
    if(*s.begin() == 0) {
        cout << "0\n";
        cout.flush();
        cin >> x;
    }else {
        x = *s.begin();
        while(1) {
            cout << x << "\n";
            cout.flush();
            cin >> x;
            if(x == -1) return;
        }
    }
}

E1. Salyg1n and Array (simple version)

题意
未知一个长度为\(n\)的数组,每次可以查询长度大小为\(k\)的区间异或和,每次查询完毕,整个长度大小为\(k\)的段会翻转,最多查询100次,数据范围看原题,让你输出\(1-n\)的异或和。
线索

提示1

题目\(n\)很小,\(k\)通过计算也很小,想想暴力枚举,值得一提的是\(n\)\(k\)都是偶数。

提示2

我们显然可以\(n\%k==0\),直接查询每一块异或和最后就是答案,那如果有余数呢?根据\(n\)\(k\)的性质,余数定然也是一个偶数。

提示3

查询\([1, k]\)\([2, k + 1]\)得到的就是\(a[k]\)\(a[k + 1]\)的异或值,这样我们就可以处理掉余数的异或值的和了。

代码

点击查看代码
懒得放了,自己写

posted on 2023-09-12 14:50  C2-103  阅读(55)  评论(0)    收藏  举报

导航