Educational Codeforces Round 75

目录

  • Contest Info
  • Solutions
    • A. Broken Keyboard
    • B. Binary Palindromes
    • C. Minimize The Integer
    • D. Salary Changing
    • E2. Voting (Hard Version)

Contest Info



Practice Link

Solved A B C D E1 E2 F
6/7 O O O O O O -
  • O 在比赛中通过
  • ? 赛后通过
  • ! 尝试了但是失败了
  • - 没有尝试

Solutions


A. Broken Keyboard

题意:
有一个打字机,如果某个按键是好的,那么按下那个按键之后会在打字槽中追加一个该字符,如果是坏的则会追加两个。
现在给出打印槽中最后的结果,问有哪些按键能确定一定是好的。

思路:
将连续的相同字符取出来,如果长度为奇数,那么一定能确定该字符对应的按键是好的。

代码:

view code

#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#define fi first
#define se second
#define endl "\n"
using namespace std;
using db = double;
using ll = long long;
using ull = unsigned long long;
using pII = pair <int, int>;
using pLL = pair <ll, ll>;
constexpr int mod = 1e9 + 7;
template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; }
template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
inline int rd() { int x; cin >> x; return x; }
template <class T> inline void rd(T &x) { cin >> x; }
template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }
#define dbg(x...) do { cout << "\033[32;1m" << #x << " -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template <class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; err(args...); }
inline void pt() { cout << endl; }
template <class T, class... Ts> void pt(const T& arg, const Ts&... args) { cout << arg << ' '; pt(args...); }
template <template<typename...> class T, typename t, typename... A>
void pt(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; pt(args...); }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
//head
constexpr int N = 1e5 + 10;
int n, cnt[30]; string s;
void run() {
    cin >> s;
    memset(cnt, -1, sizeof cnt);
    for (int i = 0, len = s.size(), num = 0; i <= len; ++i) {
        if (i == len) {
            if (num & 1) {
                cnt[s[i - 1] - 'a'] = 1;
            }
        } else if (i && s[i] != s[i - 1]) {
            if (num & 1) {
                cnt[s[i - 1] - 'a'] = 1;
            }
            num = 0;
        }
        ++num;
    }
    for (int i = 0; i < 26; ++i) if (cnt[i] > 0)
        cout << char(i + 'a');
    cout << endl;

}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cout << fixed << setprecision(20);
    int _T = rd();
    while (_T--) run();
    return 0;
}

B. Binary Palindromes

题意:
给出\(n\)个\(01\)串,可以任意交换任意两个字符串的任意两个位置的字符,问最终最多能有多少回文串。

思路:
任意交换,只需要考虑\(0\)有多少个,\(1\)有多少个,然后根据原串长度贪心构造。

代码:

view code

#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#define fi first
#define se second
#define endl "\n"
using namespace std;
using db = double;
using ll = long long;
using ull = unsigned long long;
using pII = pair <int, int>;
using pLL = pair <ll, ll>;
constexpr int mod = 1e9 + 7;
template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; }
template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
inline int rd() { int x; cin >> x; return x; }
template <class T> inline void rd(T &x) { cin >> x; }
template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }
#define dbg(x...) do { cout << "\033[32;1m" << #x << " -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template <class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; err(args...); }
inline void pt() { cout << endl; }
template <class T, class... Ts> void pt(const T& arg, const Ts&... args) { cout << arg << ' '; pt(args...); }
template <template<typename...> class T, typename t, typename... A>
void pt(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; pt(args...); }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
//head
constexpr int N = 1e5 + 10;
int n, cnt[2], len[110];
void run() {
    n = rd();
    cnt[0] = cnt[1] = 0;
    for (int i = 1; i <= n; ++i) {
        string s; cin >> s;
        len[i] = s.size();
        for (auto &c : s) ++cnt[c - '0'];
    }
    sort(len + 1, len + 1 + n);
    int res = 0;
    for (int i = 1; i <= n; ++i) {
        if (len[i] & 1) {
            if (cnt[0] & 1) {
                --cnt[0];
            } else if (cnt[1] & 1) {
                --cnt[1];
            } else if (cnt[0]) {
                --cnt[0];
            } else if (cnt[1]) {
                --cnt[1];
            } else {
                break;
            }
            --len[i];
        }
        if (len[i] > cnt[0]) {
            if (cnt[0] & 1) {
                len[i] = len[i] - cnt[0] + 1;
                cnt[0] = 1;
            } else {
                len[i] -= cnt[0];
                cnt[0] = 0;
            }
        } else {
            cnt[0] -= len[i];
            len[i] = 0;
        }
        if (len[i] > cnt[1]) {
            if (cnt[1] & 1) {
                len[i] = len[i] - cnt[1] + 1;
                cnt[1] = 1;
            } else {
                len[i] -= cnt[1];
                cnt[1] = 0;
            }
        } else {
            cnt[1] -= len[i];
            len[i] = 0;
        }
        if (len[i]) break;
        ++res;
    }
    pt(res);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cout << fixed << setprecision(20);
    int _T = rd();
    while (_T--) run();
    return 0;
}

C. Minimize The Integer

题意:
给出一个\(n\)位的整数,可能有前导\(0\),现在可以任意交换两个相邻的并且奇偶性不同的数的位置,最终结果也可以存在前导\(0\),问最终结果的最小值是多少。

思路:
显然,所有奇偶性相同的数的相对位置不变,那么将奇数取出来,偶数取出来,然后贪心取头即可。

代码:

view code

#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#define fi first
#define se second
#define endl "\n"
using namespace std;
using db = double;
using ll = long long;
using ull = unsigned long long;
using pII = pair <int, int>;
using pLL = pair <ll, ll>;
constexpr int mod = 1e9 + 7;
template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; }
template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
inline int rd() { int x; cin >> x; return x; }
template <class T> inline void rd(T &x) { cin >> x; }
template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }
#define dbg(x...) do { cout << "\033[32;1m" << #x << " -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template <class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; err(args...); }
inline void pt() { cout << endl; }
template <class T, class... Ts> void pt(const T& arg, const Ts&... args) { cout << arg << ' '; pt(args...); }
template <template<typename...> class T, typename t, typename... A>
void pt(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; pt(args...); }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
//head
constexpr int N = 3e5 + 10;
int n; char s[N];
void out(vector <int> &vec) {
    cout << vec.back();
    vec.pop_back();
}
void run() {
    vector <int> vec[2];
    cin >> (s + 1);
    for (int i = 1; s[i]; ++i) {
        int num = s[i] - '0';
        vec[num & 1].push_back(num);
    }
    reverse(vec[0].begin(), vec[0].end());
    reverse(vec[1].begin(), vec[1].end());
    while (!vec[0].empty() || !vec[1].empty()) {
        if (vec[0].empty()) {
            out(vec[1]);
        } else if (vec[1].empty()) {
            out(vec[0]);
        } else {
            if (vec[0].back() < vec[1].back()) {
                out(vec[0]);
            } else {
                out(vec[1]);
            }
        }
    }
    cout << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cout << fixed << setprecision(20);
    int _T; cin >> _T;
    while (_T--) run();
    return 0;
}

D. Salary Changing

题意:
有\(n\)个人,你是老板,你手里有\(s\)元钱,要给这\(n\)个人发工资,每个人工资的范围是\([l_i, r_i]\),要如何发工资使得你的钱够用并且\(n\)个人工资的中位数最高。

思路:
首先给每个人发\(l_i\)工资,那么得到一个答案的下界,那么发现这个下界到\(INF\)这个范围,答案具有单调性,二分然后贪心\(check\)即可。

代码:

view code

#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#define fi first
#define se second
#define endl "\n"
using namespace std;
using db = double;
using ll = long long;
using ull = unsigned long long;
using pII = pair <int, int>;
using pLL = pair <ll, ll>;
constexpr int mod = 1e9 + 7;
template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; }
template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
inline int rd() { int x; cin >> x; return x; }
template <class T> inline void rd(T &x) { cin >> x; }
template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }
#define dbg(x...) do { cout << "\033[32;1m" << #x << " -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template <class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; err(args...); }
inline void pt() { cout << endl; }
template <class T, class... Ts> void pt(const T& arg, const Ts&... args) { cout << arg << ' '; pt(args...); }
template <template<typename...> class T, typename t, typename... A>
void pt(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; pt(args...); }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
//head
constexpr int N = 2e5 + 10;
int n; ll s;
pII a[N];
bool check(ll x) {
    int l = 0, r = 0;
    ll remind = s;
    for (int i = 1; i <= n; ++i) {
        if (a[i].se < x) {
            remind -= a[i].fi;
            ++l;
        } else if (a[i].fi > x) {
            remind -= a[i].fi;
            ++r;
        }
    }
    if (l > n / 2 || r > n / 2) return false;
    for (int i = 1; i <= n; ++i) {
        if (a[i].fi <= x && a[i].se >= x) {
            if (l < n / 2) {
                ++l;
                remind -= a[i].fi;
            } else {
                remind -= x;
            }
        }
    }
    return remind >= 0;
}
void run() {
    cin >> n >> s;
    for (int i = 1; i <= n; ++i) a[i].fi = rd(), a[i].se = rd();
    sort(a + 1, a + 1 + n);
    ll l = a[n / 2 + 1].fi, r = 1e9, res = l;
    while (r - l >= 0) {
        ll mid = (l + r) >> 1;
        if (check(mid)) {
            res = mid;
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    pt(res);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cout << fixed << setprecision(20);
    int _T = rd();
    while (_T--) run();
    return 0;
}

E2. Voting (Hard Version)

题意:
有\(n\)个人,你可以花费\(p_i\)让第\(i\)个人投票,或者拉够\(m_i\)个人为你投票,这个人就会为你投票。
现在你想让所有人都为你投票,需要花费的最小代价是多少?

思路:
假设我知道有\(x\)个人不需要花费代价能让他们为我免费投票,那么我假设刚开始对每个人都付了钱让他们投票,现在就是要去除\(x\)个人的花费,使得去除的花费最大。
那么我们从\(i \in [x, n]\)扫一遍,用一个大根堆维护\(m_i < i\)的所有人的最大\(p_i\),每次取出堆顶的\(p_i\)即可。
并且容易发现\(x\)具有单调性,直接二分即可。

代码:

view code

#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#define fi first
#define se second
#define endl "\n"
using namespace std;
using db = double;
using ll = long long;
using ull = unsigned long long;
using pII = pair <int, int>;
using pLL = pair <ll, ll>;
constexpr int mod = 1e9 + 7;
template <class T1, class T2> inline void chadd(T1 &x, T2 y) { x += y; while (x >= mod) x -= mod; while (x < 0) x += mod; }
template <class T1, class T2> inline void chmax(T1 &x, T2 y) { if (x < y) x = y; }
template <class T1, class T2> inline void chmin(T1 &x, T2 y) { if (x > y) x = y; }
inline int rd() { int x; cin >> x; return x; }
template <class T> inline void rd(T &x) { cin >> x; }
template <class T> inline void rd(vector <T> &vec) { for (auto &it : vec) cin >> it; }
#define dbg(x...) do { cout << "\033[32;1m" << #x << " -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template <class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << ' '; err(args...); }
template <template<typename...> class T, typename t, typename... A>
void err(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; err(args...); }
inline void pt() { cout << endl; }
template <class T, class... Ts> void pt(const T& arg, const Ts&... args) { cout << arg << ' '; pt(args...); }
template <template<typename...> class T, typename t, typename... A>
void pt(const T <t> &arg, const A&... args) { for (auto &v : arg) cout << v << ' '; pt(args...); }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll qpow(ll base, ll n) { ll res = 1; while (n) { if (n & 1) res = res * base % mod; base = base * base % mod; n >>= 1; } return res; }
//head
constexpr int N = 2e5 + 10;
int n; vector <vector<int>> vec;
ll gao(int x) {
    ll tot = 0;
    priority_queue <int, vector<int>, less<int>> pq;
    for (int i = 1; i <= n; ++i) {
        for (auto &it : vec[i]) pq.push(it);
        if (i >= x) {
            if (pq.empty()) return 0;
            tot += pq.top(); pq.pop();
        }
    }
    return tot;
}
void run() {
    n = rd();
    vec.clear(); vec.resize(n + 1);
    ll tot = 0;
    for (int i = 1, m, p; i <= n; ++i) {
        m = rd(); p = rd();
        vec[m + 1].push_back(p);
        tot += p;
    }
    int l = 1, r = n; ll Max = 0;
    while (r - l >= 0) {
        int mid = (l + r) >> 1;
        ll tmp = gao(mid);
        chmax(Max, tmp);
        //dbg(l, r, mid, Max);
        if (tmp > 0) {
            r = mid - 1;
        } else {
            l = mid + 1;
        }
    }
    pt(tot - Max);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    cout << fixed << setprecision(20);
    int _T = rd();
    while (_T--) run();
    return 0;
}

原文地址:https://www.cnblogs.com/Dup4/p/11736048.html

时间: 2024-08-30 14:12:53

Educational Codeforces Round 75的相关文章

Educational Codeforces Round 75 ABCD题解

A. Broken Keyboard Description 给出一串小写字母字符序列,连续出现两次的字母为坏掉的,按字典序输出所有没有坏掉的字母. Solution 模拟暴力删除字母,注意相同字母的去重. 1 #include <algorithm> 2 #include <cctype> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cst

Educational Codeforces Round 75 (Rated for Div. 2) C. Minimize The Integer

链接: https://codeforces.com/contest/1251/problem/C 题意: You are given a huge integer a consisting of n digits (n is between 1 and 3?105, inclusive). It may contain leading zeros. You can swap two digits on adjacent (neighboring) positions if the swappi

Educational Codeforces Round 75 (Rated for Div. 2) A. Broken Keyboard

链接: https://codeforces.com/contest/1251/problem/A 题意: Recently Polycarp noticed that some of the buttons of his keyboard are malfunctioning. For simplicity, we assume that Polycarp's keyboard contains 26 buttons (one for each letter of the Latin alph

Educational Codeforces Round 75 (Rated for Div. 2) B. Binary Palindromes

链接: https://codeforces.com/contest/1251/problem/B 题意: A palindrome is a string t which reads the same backward as forward (formally, t[i]=t[|t|+1?i] for all i∈[1,|t|]). Here |t| denotes the length of a string t. For example, the strings 010, 1001 and

Educational Codeforces Round 75 (Rated for Div. 2) D. Salary Changing

链接: https://codeforces.com/contest/1251/problem/D 题意: You are the head of a large enterprise. n people work at you, and n is odd (i.?e. n is not divisible by 2). You have to distribute salaries to your employees. Initially, you have s dollars for it,

Educational Codeforces Round 75 (Rated for Div. 2)

(体验到了胡出一道题但是写锅的绝望呢) A: 送分题. #include<bits/stdc++.h> #define maxn 100005 #define maxm 500005 #define inf 0x7fffffff #define ll long long using namespace std; bool may[30]; char str[maxn]; inline int read(){ int x=0,f=1; char c=getchar(); for(;!isdigi

Educational Codeforces Round 75 (Rated for Div. 2)D(二分)

#define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;pair<int,int>a[200007];int n;long long s;bool check(int x){ int num=0; long long sum=s; for(int i=n;i;--i){ if(a[i].first>=x) ++num; else if(a[i].second>=x&&s

Educational Codeforces Round 23 F. MEX Queries(线段树)

题目链接:Educational Codeforces Round 23 F. MEX Queries 题意: 一共有n个操作. 1.  将[l,r]区间的数标记为1. 2.  将[l,r]区间的数标记为0. 3.  将[l,r]区间取反. 对每个操作,输出标记为0的最小正整数. 题解: hash后,用线段树xjb标记一下就行了. 1 #include<bits/stdc++.h> 2 #define ls l,m,rt<<1 3 #define rs m+1,r,rt<&l

Educational Codeforces Round 21 F. Card Game(网络流之最大点权独立集)

题目链接:Educational Codeforces Round 21 F. Card Game 题意: 有n个卡片,每个卡片有三个值:p,c,l; 现在让你找一个最小的L,使得满足选出来的卡片l<=L,并且所有卡片的p的和不小于k. 选择卡片时有限制,任意两张卡片的c之和不能为质数. 题解: 和hdu 1565 方格取数(2)一样,都是求最大点权独立集. 不难看出来,这题再多一个二分. 注意的是在构造二部图的时候,按照c值的奇偶性构造. 当c==1时要单独处理,因为如果有多个c==1的卡片,