VP Educational Codeforces Round 75 (Rated for Div. 2)


A. Broken Keyboard

题意:\(26\)个按键对\(26\)个字母,有些按键是坏的。好的按键按下后会出现一个字母,坏的会出现两个。现在给出一个输出序列。求哪些按键一定是好的。

好的按键需要满足,出现次数是奇数,或者有连续一段的长度是奇数。

点击查看代码
void solve() {
    std::string s;
    std::cin >> s;
    std::array<int, 26> st{}, cnt{};
    for (int i = 0; i < s.size(); ++ i) {
    	int j = i;
    	while (j + 1 < s.size() && s[i] == s[j + 1]) {
    		++ j;
    	}

    	cnt[s[i] - 'a'] += j - i + 1;
    	st[s[i] - 'a'] |= j - i + 1 & 1;
    	i = j;
    }

    std::string ans;
    for (int i = 0; i < 26; ++ i) {
    	if (cnt[i] % 2 || st[i]) {
    		ans += (char)('a' + i);
    	}
    }
    std::cout << ans << "\n";
}

B. Binary Palindromes

题意:给你\(n\)\(01\)串,每次你可以交换任意两个串任意两个位置的数。求最多凑出多少个回文串。

先不讨论和其它串交换,看每个串能不能自己变成回文。记\(cnt0\)\(0\)的个数,\(cnt1\)\(1\)的个数。那么只要\(cnt0, cnt1\)不同为奇数,就可以变成回文。然后不能变成回文的可以两两操作变成回文。还有一个例外就是一个长度为奇数的可以变成回文的串,可以和不能变成回文的串操作使得它变成回文。

点击查看代码
void solve() {
    int n;
    std::cin >> n;
    std::vector<std::string> s(n);
    int cnt = 0, flag = 0, ans = 0;
    for (int i = 0; i < n; ++ i) {
    	std::cin >> s[i];
    	int cnt0 = std::ranges::count(s[i], '0');
    	int cnt1 = std::ranges::count(s[i], '1');
    	if (cnt0 % 2 && cnt1 % 2) {
    		++ cnt;
    	} else {
    		++ ans;
    		flag |= cnt0 % 2 || cnt1 % 2;
    	}
    }

    ans += cnt / 2 * 2;
    ans += flag && cnt % 2;
    std::cout << ans << "\n";
}


C. Minimize The Integer

题意:给你一个数字串,如果相邻的两个数字奇偶性不同就可以交换。求最小数字串。

发现对于奇偶性相同的数字,它们的相对顺序是不变的。那么可以分奇偶存,每次拿最小的。

点击查看代码
void solve() {
    std::string s;
    std::cin >> s;
    std::string a, b;
    for (auto & c : s) {
    	if (c - '0' & 1) {
    		a += c;
    	} else {
    		b += c;
    	}
    }

    std::string ans;
    std::ranges::reverse(a);
    std::ranges::reverse(b);
    while (a.size() || b.size()) {
    	if (b.empty() || (a.size() && a.back() < b.back())) {
    		ans += a.back();
    		a.pop_back();
    	} else  {
    		ans += b.back();
    		b.pop_back();
    	}
    }

    std::cout << ans << "\n";
}

D. Salary Changing

题意:有\(n\)个区间\([l_i, r_i]\),你要在每个区间选一个数然后减去它,你总共有\(s\)元。求最大的中位数。

考虑二分。
假设当前是\(x\),那么大于等于它的数字需要超过\(\lfloor \frac{n + 1}{2} \rfloor\),把\(r_i < x\)\(l_i > x\)的给\(l_i\)。剩下的都是包含\(x\)的,我们按\(l_i\)从大到小选,如果大于等于\(x\)的数还不够就选\(x\),否则选\(l_i\)。最后只要总和小于等于\(s\)和选择个数大于等于\(\lfloor \frac{n + 1}{2} \rfloor\)就行。

点击查看代码
void solve() {
    int n;
    i64 s;
    std::cin >> n >> s;
    std::vector<int> l(n), r(n);
    for (int i = 0; i < n; ++ i) {
    	std::cin >> l[i] >> r[i];
    }

    auto check = [&](int x) -> bool {
    	int cnt = 0;
    	i64 sum = 0;
    	std::vector<int> val;
    	for (int i = 0; i < n; ++ i) {
    		if (r[i] < x) {
    			sum += l[i];
    		} else {
    			if (l[i] > x) {
    				sum += l[i];
    				++ cnt;
    			} else {
	    			val.push_back(l[i]);
    			}
    		}
    	}

    	std::ranges::sort(val, std::greater<>());
    	for (int i = 0; i < val.size(); ++ i) {
    		if (cnt < n / 2 + 1) {
    			++ cnt;
    			sum += x;
    		} else {
    			sum += val[i];
    		}
    	}

    	return sum <= s && cnt >= n / 2 + 1;
    };

    int lo = 1, hi = 1e9;
    while (lo < hi) {
    	int mid = lo + hi + 1 >> 1;
    	if (check(mid)) {
    		lo = mid;
    	} else {
    		hi = mid - 1;
    	}
    }

    std::cout << lo << "\n";
}

E1 && E2. Voting

题意:有\(n\)个人,每个人你可以选择花费\(p_i\)让它加入你,或者已经有\(m_i\)个人以上加入你他就会自动加入你。求所有人加入你的最少花费。

考虑按\(m\)从大到小排序。
对于第\(i\)个人,假设后面的人都加入了,前面有一个集合\(P\)表示这里面的人没被氪金,但可能自动加入。那么如果\(n - |P| < m_i\),那么\(|P|\)里的人因为\(m\geq m_i\),则这些人都不可能自动加入了,那么必须从这些人里买人。显然应该从小到大买,可以用小根堆维护这个集合。
随着\(i\)的增大,如果一直不买人,则\(n - |P|\)一直变小,所以到后面总会购买。这时只要满足了\(m_i\),则其它比它大的也会满足。

点击查看代码
void solve() {
    int n;
    std::cin >> n;
    std::vector<std::pair<int, int>> a(n);
    for (int i = 0; i < n; ++ i) {
    	std::cin >> a[i].first >> a[i].second;
    }

    std::ranges::sort(a, std::greater<>());
    std::priority_queue<int, std::vector<int>, std::greater<int>> heap;
    i64 ans = 0;
    for (auto & [x, y] : a) {
    	heap.push(y);
    	while (n - (int)heap.size() < x) {
    		ans += heap.top();
    		heap.pop();
    	}
    }
    std::cout << ans << "\n";
}
posted @ 2025-05-04 02:00  maburb  阅读(8)  评论(0)    收藏  举报