Codeforces Round #650 (Div. 3)

B

计算偶数位置上的奇数 和 奇数位置上的偶熟 个数是否相等,

不相等的话,就不可能变成 \(good\)

相等的话,每次\(swap\) 一下消除一对,最小的操作数就是偶数(奇数)的个数

#include <bits/stdc++.h>
using namespace std;
int main() {
    int t;
    cin >> t;
    while(t --) {
        int n;
        cin >> n;
        vector<int> a(n,0);
        for(int i = 0;i < n; ++i) cin >> a[i];
        int cnt = 0,even = 0,odd = 0;
        for(int i = 0;i < n; i += 2) {
            if(a[i] % 2 != 0) even ++;
        }
        for(int i = 1;i < n; i += 2) {
            if(a[i] % 2 != 1) odd ++;
        }
        if(even != odd) cout << "-1";
        else cout << even ;
        cout << endl;
    }
    return 0;
}

C

转化下思想,用 \(0\) 来找 \(1\) ,而不是傻傻的直接模拟

#include <bits/stdc++.h>
using namespace std;
int main() {
    int t;
    cin >> t;
    while(t --) {
        int n,k,cnt = 0;
        char ch;
        cin >> n >> k;
        vector<int> a(n,0);
        for(int i = 0;i < n; ++i) {
            cin >> ch;
            if(ch == '1') a[i] = 1;
            else a[i] = 0;
        }
        for(int i = 0;i < n; ++i) {
            if(a[i] == 0) {
                int j = i + 1;
                while(j < n && a[j] == 0 && j - i <= k) ++ j;
                if(j - i > k || j == n) {
                    cnt ++;
                    i += k;
                }
                else i = j - 1;
            }
            else i += k;
        }
        cout << cnt << endl;
    }
    return 0;
}

参考

Kanoon

D

要找对方法模拟

每次找到一组 \(0\)\(b[]\) 中的其他值都减去这个位置,就更新了,而当前的 \(0\) 一定是最大值,在单词中找到,然后加到答案里面即可

#include <bits/stdc++.h>
using namespace std;
int num[60],dict[30];
bool st[60];
int n;
void word(int x) {
    for(int i = 0;i < n; ++i) {
        if(num[i]) num[i] -= abs(i - x);
    }
}
int main() {
    int t;
    cin >> t;
    string s;
    while(t --) {
        memset(num,0,sizeof num);
        memset(dict,0,sizeof dict);
        memset(st,0,sizeof st);
        cin >> s >> n;
        vector<char> str(n);
        for(int i = 0;i < s.length(); ++i) dict[s[i] - 'a'] ++;
        for(int i = 0;i < n; ++i) cin >> num[i];
        while(1) {
            bool flag = 1;
            vector<int> v;
            for(int i = 0;i < n; ++i) {
                if(num[i] == 0 && st[i] == 0) {
                    v.push_back(i);
                    st[i] = 1;
                    flag = 0;
                    
                }
            }
            int idx = 0;
            for(int i = 25;i >= 0; --i) {
                if(dict[i]) {
                    if(dict[i] >= v.size()) {
                        idx = i;
                        dict[i] = 0;
                        break;
                    }
                    dict[i] = 0;
                }
            }
            for(auto i : v) {
                word(i);
                str[i] = idx + 'a';
            }
            if(flag) break;
        }
        for(int i = 0;i < n; ++i) cout << str[i];
        cout << endl;
    }
    return 0;
}

参考

无名菜鸟1

siven

E

二分 \(k\) 的因子,有好多小坑

yxc的那个模板不太会用,好像处理不了这种问题

这个二分模板很舒服

while(l <= r) {
	int mid = l + r >> 1;
	if(check(mid)) r = mid - 1;
	else l = mid + 1;
}
#include <bits/stdc++.h>
using namespace std;
int num[30];
bool check(int x,int k) {
    for(int i = 0;i < 26; ++i) {
        x -= num[i] / k;
        if(x <= 0) return 1;
    }
    return 0;
}
int main() {
    int t;
    cin >> t;
    string s;
    int n,k;
    while(t --) {
        memset(num,0,sizeof num);
        cin >> n >> k >> s;
        int ans = 0;
        for(int i = 0;i < n; ++i) {
            ans = max(ans,++ num[s[i] - 'a']);
        }
        for(int i = 2;i <= k; ++i) {
            if(k % i != 0) continue;
            int l = 1,r = n / i;
            while(l <= r) {
                int mid = l + r >> 1;
                if(check(i,mid)) {
                    l = mid + 1;
                    ans = max(ans,mid * i);
                }
                else r = mid - 1;
            }
        }
        cout << ans << endl;
    }
}

参考

无名菜鸟1

issue敲腻害

F

离散化一遍,找到最长连续子序列,\(n-ans\) 就是答案

因为最长连续子序列哪一块肯定不用动,只需要移动剩下的数字即可

#include <bits/stdc++.h>
using namespace std;
const int N = 3010;
int a[N],b[N];
int main() {
    int t,n;
    cin >> t;
    while(t --) {
        cin >> n;
        for(int i = 0;i < n; ++i) {
            cin >> a[i];
            b[i] = a[i];
        }
        sort(b,b + n);
        for(int i = 0;i < n; ++i) {
            a[i] = lower_bound(b,b + n,a[i]) - b;
        }
        int ans = 0,cnt = 0;
        while(cnt < n) {
            int len = 0;
            for(int i = 0;i < n; ++i) {
                if(cnt == a[i]) {
                    cnt ++;
                    len ++;
                }
            }
            ans = max(ans,len);
        }
        cout << n - ans<< endl;
    }
    return 0;
}

参考

Accelerator

posted @ 2020-07-18 00:05  南风--  阅读(137)  评论(0编辑  收藏  举报