1.30 vp Codeforces Round #846 (Div. 2)

时间:2023-01-30
本文章向大家介绍1.30 vp Codeforces Round #846 (Div. 2),主要内容包括A - Hayato and School、、题意、思路、B - GCD Partition、D - Bit Guessing Game、题意(交互)、使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

A - Hayato and School、

题意

给出长度为n的序列a,要求判断是否存在三个数之和为奇数,若有则输出YES且输出这三个数的下标,否则输出NO

思路

数字和为奇数的情况只有奇 + 偶, 而三个数就可以是奇奇奇,奇偶偶这两种情况。
将序列分为奇偶两个部分,然后判断是否存在这两种情况中的一种即可

void solve() {
	int n;
	cin >> n;
	vector<int> a (n + 1);
	vector<int> o, e;
	for (int i = 1; i <= n; i ++) {
		cin >> a[i];
		if (a[i] % 2 == 1) o.push_back(i);
		else e.push_back(i);
	}
	
	if (o.size() >= 3 || e.size() >= 2 && o.size() >= 1) {
		cout << "YES" << endl;
		if (o.size() >= 3) {
			for (int i = 0; i < 3; i ++) cout << o[i] << ' ';
			cout << endl;
		}else {
			cout << e[0] << ' ' << e[1] << ' ' << o[0] << endl;
		}
	}else {
		cout << "NO" << endl;
	}

}
\[\]

B - GCD Partition

题意

给出一个长度为n的序列,你可以将他们分为k份(k > 1),每份之和为\(b_i\)
例如:
序列:123456
分为三份
12,34,56
则b1 = 3, b2 = 7, b3 = 11
问怎么分可以使b数组所有元素的gcd最大

思路

因为k > 1,故而整个数组一定是被分为2份以上的,其中分的时候是按原数组顺序
所以我们可以想到只需要把数组分为两段即可,因为若存在倍数关系,则在两段的时候一定会出现,例如1 2 1 1 1 3,我们可以将它分为12, 111, 3三份gcd是3,但是把它分为两份12, 1113时3, 6的gcd也是3
因此对于序列的前缀和剩余部分进行gcd即可

LL gcd(LL a, LL b) {
	return b ? gcd(b, a % b) : a;
}

void solve() {
	int n;
	cin >> n;
	vector<int> a(n + 1);
	LL sum = 0;
	for (int i = 1; i <= n; i ++) {
		cin >> a[i];
		sum += a[i];
	}
	
	LL tmp = 0, mx = 0;
	
	for (int i = 1; i < n; i ++) {
		tmp += a[i];
		mx = max(mx, gcd(tmp, sum - tmp));
	}
	
	cout << mx << endl;
}
\[\]

D - Bit Guessing Game

题意(交互)

你要猜题目给出的数字。
玩法:最开始的时候,会给你给出数字二进制上1的数量
然后你可以向系统输入x,然后给出的数字将减去x,再给你新的数字的二进制上1的数量
要求提问次数不超过30次,输出给出的数字

思路

看的大佬思路是lowbit,每次提问减去上次提问的lowbit + 1,然后以新的数量t和之前剩下的数量比较,看多了多少个1,将他们减掉即可,这样每次都可以消掉lowbit上的1,所以每次只会操作n次(0 < n < 30)
例如:
101100
-1
101011
-(100)2
100111
-(1000)2
11111
-(100000)2
ans即为上面减去的二进制数之和

void ask(int x) {
	cout << "- " << x << endl;
}
 
void solve() {
	int ans = 0, last = 1;
	int cnt;
	cin >> cnt;
	while (cnt) {
		ask(last);
		int t;
		cin >> t;
		ans |= (1 << (t - cnt + 1));
		last = (1 << (t - cnt + 1));
		cnt --;
	}
	cout << "! " << ans << endl;
}

总结

思维较之前有增长,交互题可能比较简单,所以也有思路,但是没写出来

原文地址:https://www.cnblogs.com/lbzbk/p/17077049.html