首页 > 其他分享 >Codeforces Round 973 (Div. 2)

Codeforces Round 973 (Div. 2)

时间:2024-09-21 21:23:14浏览次数:1  
标签:cnt 973 val Codeforces long solve mp using Div

Sol CF2013

A

每次最多操作 \(\min(x, y)\),故答案为 \(\lceil\frac{n}{\min(x, y)}\rceil\)。

#include <bits/stdc++.h>
using namespace std;
using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128;

#define IOS
#define MULTI

void solve() {
	int n, x, y;
	cin >> n >> x >> y;
	x = min(x, y);
	cout << (n + x - 1) / x << '\n';
}

int main() {
#ifdef IOS
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
#endif
#ifdef MULTI
	int TestCase = 1;
	for (cin >> TestCase; TestCase--;) solve();
#else
	solve();
#endif
	return 0;
}

B

若 \(i < j < k\),\(j\) 把 \(i\) 打败,\(k\) 把 \(j\) 打败,最后的答案为 \(a_k + a_i - a_j\)。

可知 \(n\) 必须保留,前面所有都必须被某个人打败。

又 \(n - 1\) 必须被 \(n\) 打败,即答案一定有 \(a_n - a_{n-1}\)。

那么只需要让 \(n - 1\) 先打败 \([1, n - 2]\),就可构造最大答案 \(a_1 + a_2 + \cdots + a_{n - 2} - a_{n - 1} + a_n\)。

#include <bits/stdc++.h>
using namespace std;
using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128;

#define IOS
#define MULTI
i < j < k

j eat i
k eat j


n + 1 + 2 + ... + (n - 2) - (n - 1)

void solve() {
	int n;
	cin >> n;
	vector<int> a(n);
	for (int &x : a)
		cin >> x;
	// sort(begin(a), end(a));
	i64 sum = 0;
	for (int i = 0; i < n; ++i)
		if (i != n - 2) sum += a[i];
	cout << sum - a[n - 2] << '\n';
}

int main() {
#ifdef IOS
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
#endif
#ifdef MULTI
	int TestCase = 1;
	for (cin >> TestCase; TestCase--;) solve();
#else
	solve();
#endif
	return 0;
}

C

首先考虑从前缀或后缀开始猜,那么每次只需要一个询问就能确定下一个字符。

考虑怎么搞到前缀/后缀。不妨一开始先随便问一个字符,然后不断在这个字符后面添加 0/1,再询问,就可以得到一个极长的存在于原串 \(s\) 中的子串 \(t\)。

为什么称为极长?因为 \(t\) 后面无论添加 0 还是 1 都无法更长。那么,\(t\) 就是一个后缀!并且这个 \(t\) 只是后缀!因为假设 \(t\) 出现在了 \(s\) 中一个非后缀的位置,显然 \(t\) 不是极长的(还可以往后拓展)。

那么不断在 \(t\) 前面加 0/1 即可得到答案。注意处理边界防止询问次数过多,可参考代码。

#include <bits/stdc++.h>
using namespace std;
using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128;

#define IOS
#define MULTI

void solve() {
	int n;
	cin >> n;
	auto ask = [=](string s) -> int {
		int judge;
		cout << "? " << s << endl;
		cin >> judge;
		return judge;
	};
	auto guess = [=](string s) -> void {
		cout << "! " << s << endl;
		return;
	};
	auto sol = [=](string s) {
		for (int len = 2; len <= n; ++len) {
			s.push_back('0');
			if (ask(s)) continue;
			else {
				s[len - 1] = '1';
				if (ask(s)) continue;
				else {
					s.pop_back();
					break;
				}
			}
		}
		return s;
	};
	if (!ask("0")) {
		string res;
		for (int i = 1; i <= n; ++i)
			res.push_back('1');
		guess(res);
	} else {
		string suf = sol("0");
		while (int(suf.size()) < n) {
			suf = '0' + suf;
			if (!ask(suf)) suf[0] = '1';
		}
		guess(suf);
	}
}

int main() {
#ifdef IOS
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
#endif
#ifdef MULTI
	int TestCase = 1;
	for (cin >> TestCase; TestCase--;) solve();
#else
	solve();
#endif
	return 0;
}

D

看完题目发现可以模拟。从前往后处理,每次新加入一个数,我们考虑尽可能把这个数调大。当然如果这个数是 \(\max\) 就不用调了,也没办法调(所以算法是正确的)。

如何尽可能调大?就是找前面的最大值,将其减小,添加到当前这个数。如果开个 map,就可以 \(O(\log n)\) 找到这样的数,调完当前数后,把当前数塞回去。均摊一下时间复杂度 \(O(n\log n)\)。

#include <bits/stdc++.h>
using namespace std;
using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128;

#define IOS
#define MULTI

void solve() {
	int n;
	cin >> n;
	vector<i64> a(n);
	for (auto &x : a)
		cin >> x;
	map<i64, int> mp;
	mp[0] = 0;
	// 假设 val -= k
	// 1. k <= (val - a[i]) / (cnt + 1)
	// 2. k <= val - sev
	// cout << "n = " << n << '\n';
	for (int i = 0; i < n; ++i) {
		while (int(mp.size()) > 1) {
			auto [val, cnt] = *rbegin(mp);
			mp.erase(val);
			i64 sev = rbegin(mp) -> first;
			i64 k = min(val - sev, (val - a[i]) / (cnt + 1));
			if (k < 0) k = 0;
			a[i] += cnt * k;
			mp[val - k] += cnt;
			if (k == 0 || val == 0) break;
		}
	// 假设 cnt -= k
	// 1. k < cnt
	// 2. a[i] + cnt < val
		while (int(mp.size()) > 1) {
			auto [val, cnt] = *rbegin(mp);
			if (val == 0) break;
			mp.erase(val);
			// i64 sev = rbegin(mp) -> first;
			i64 k = min((i64)cnt, val - a[i]) - 1;
			if (k < 0) k = 0;
			a[i] += k;
			mp[val] += cnt - k;
			mp[val - 1] += k;
			if (k == 0) break;
		}
		mp[a[i]] += 1;
		// for (auto [val, cnt] : mp)
		// 	for (int i = 0; i < cnt; ++i)
		// 		cout << val << " ";
		// cout << '\n';
	}
	i64 mn = 1e18, mx = -mn;
	for (auto [v, c] : mp)
		if (c) {
			mn = min(mn, v);
			mx = max(mx, v);
		}
	cout << mx - mn << '\n';
}

int main() {
#ifdef IOS
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
#endif
#ifdef MULTI
	int TestCase = 1;
	for (cin >> TestCase; TestCase--;) solve();
#else
	solve();
#endif
	return 0;
}

E/F

不会。

标签:cnt,973,val,Codeforces,long,solve,mp,using,Div
From: https://www.cnblogs.com/lingfunny/p/18424527

相关文章

  • Codeforces Round 973 (Div. 2) B. Battle for Survive
    题目链接:题目大意:把题目的操作翻译一下就是拿一个数去减后面的一个数,然后前面这个数会消掉。最小化最后剩下的数。思路:容易看出,最后剩下的一定是最后一个数,因为最后一个数一定不会被消去,又已知最后只剩下一个数,那么就是最后一个数。前面的所有数都要被消去,最差的情况就......
  • for循环—不同div显示不同样式
    for出来的div想要显示不同的样式,可以通过动态class,根据需要的条件指示控制样式,例如用index第一个div显示first-card的样式,第二个div显示second-card的样式<divclass="meal"><el-cardclass="meal_details"v-for="(item,index)inm......
  • POLIR-Society-Sociology-Individual-Social Identity Theory: 社会身份理论
    POLIR-Society-Sociology:社会学Individual:SocialIdentityTheory:社会身份理论InSociology,WehavethisSocialIdentifyTheory,Whichisabouthowwedefineourselvesasindividualperson,ShowcasingWhowewanttobeandHowotherpeopleseeusasaperso......
  • Educational Codeforces Round 135 (Rated for Div. 2)D. Letter Picking
    注意读题,每次拿完之后是放在开头。所以先手不败,因为最后剩下两个的时候,先手一定可以取较小值。考虑怎样会出现平局?首先已经知道了先手不败,那么对于后手来说,他追求的就是平局,也就是尽可能的保证每一步都都与先手相同。所以,如果是回文串,或者两两相同,或者回文串包两两相同的情况,才......
  • Educational Codeforces Round 136 (Rated for Div. 2) D. Reset K Edges
    这道题目我们可以考虑二分做,二分出最终的深度,然后尝试是否能使用不超过\(k\)次操作使得深度符合条件。考虑如何和判断,我们可以从根节点开始搜索,如果当前点的深度为\(mid+1\),就对当前点进行操作。但很可惜,这种贪心方法可以很容易的举出反例,比如深度为\(mid\)的点下面有很多个叶......
  • OpenCV(cv::divide())
    目录1.函数定义2.工作原理3.示例3.1矩阵除法3.2矩阵和标量的除法3.3使用缩放因子4.注意事项5.应用场景cv::divide()是OpenCV中用于执行数组或标量的逐元素除法操作的函数。它允许对矩阵进行元素级的除法操作,支持两种使用方式:矩阵与矩阵之间的除法,或矩阵与标量之间的......
  • Codeforces Round 972 (Div. 2)
    A.SimplePalindrome考虑到对于同一种字母无论怎么摆放,对答案的影响是相同的。所以我们可以直接把同一种字母放在一起,考虑不同中字母间为了消除回文串,必须是的同一种字母不会出现在另一种字母的两侧。因此我们只要尽可能的均分五种字母就好了。#include<bits/stdc++.h>using......
  • error: rpmdb, failed: BDB1507 Thread died in Berkeley DB library,error(-30973) fro
    rpm数据库错误,一般原因:yum更新等rpm软件安装进程被异常终止[root@49bdfccd7f61~]#yuminstall-yxxxerror:rpmdb:BDB0113Thread/process22858/140222685267712failed:BDB1507ThreaddiedinBerkeleyDBlibraryerror:db5error(-30973)fromdbenv->failchk:BDB0......
  • Codeforces Round 972 (Div. 2) 补题记录(A~C,E1)
    dproundagainA发现构造若干个\(a\)然后接若干个\(e\)接若干个\(i\)接若干个\(o\)再接若干个\(u\)且让这些字母的出现次数尽量相等最优。直接构造时间复杂度为\(O(n)\)。voidsolve(unsigned__testid=1){intn;cin>>n;F(i,0,4){intcnt=n......
  • Codeforces Round 969 (Div. 2)
    传送门A.题意:集合里有\([l,r]\),每次操作选择集合中三个互质的不同的整数并从集合中删除,最多可以进行多少次操作\(gcd(i,i+1)=1\),每次选择相邻的三个数,且第一个数为奇数,这样保证这三个数一定互质,判断\(l\)和\(r\),统计个数即可。#include<bits/stdc++.h>usingnamesp......