2022.10.17每日刷题打卡

目录

Codeforces Round #828 (Div. 3)

A. Number Replacement

 B. Even-Odd Increments

 C. Traffic Light

 D. Divisibility by 2^n

 E1. Divisible Numbers (easy version)



A. Number Replacement

题意:

一个数组和一个字符串,数组元素变成字符串字符,问能不能变成。

思路:

map扫一遍就可以了

#include <bits/stdc++.h>

void solve() {
	int n;
	std::cin >> n;
	std::vector<int>a(n);
	std::unordered_map<int, int>mymap;
	for (int i = 0; i < n; i++) {
		std::cin >> a[i];
		mymap[a[i]] = -1;
	}
	std::string s;
	std::cin >> s;
	for (int i = 0; i < n; i++) {
		if (mymap[a[i]] == -1) {
			mymap[a[i]] = i;
		} else {
			if (s[i] != s[mymap[a[i]]]) {
				std::cout << "NO\n";
				return ;
			}
			mymap[a[i]] = i;
		}
	}
	std::cout << "YES\n";
	//mymap.clear();
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	int t;
	std::cin >> t;

	while (t--) {
		solve();
	}

	return 0;
}

复盘后发现甚至不需要用map,for数组元素相等的位置字符串对应位置的字符也应该相等,否则就不可能。

#include <bits/stdc++.h>

void solve() {
	int n;
	std::cin >> n;
	std::vector<int>a(n);
	for (int i = 0; i < n; i++) {
		std::cin >> a[i];
	}
	std::string s;
	std::cin >> s;
	int flag = true;
	for (int i = 0; i < n; i++) {
		for (int j = i + 1; j < n; j++) {
			if (a[i] == a[j] && s[i] != s[j]) {
				flag  = false;
			}
		}
	}
	std::cout << (flag ? "YES\n" : "NO\n");
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	int t;
	std::cin >> t;

	while (t--) {
		solve();
	}

	return 0;
}

 B. Even-Odd Increments

每次把所有奇数元素+x或偶数元素+x,输出它的和

思路:

这里要注意一点,偶数+奇数=奇数,奇数+奇数=偶数,需要对计数器进行清零和加

#include <bits/stdc++.h>
#define int long long

void solve() {
	int n, m;
	std::cin >> n >> m;
	std::vector<int>a(n);
	int os = 0, es = 0, num1 = 0, num2 = 0;
	for (int i = 0; i < n; i++) {
		std::cin >> a[i];
		if (a[i] & 1) os += a[i], num1++;
		else es += a[i], num2++;
	}
	while (m--) {
		int op;
		std::cin >> op;
		if (op == 0) {
			int x;
			std::cin >> x;
			es += num2 * x;
			if (x & 1)num1 += num2, num2 = 0;
		} else {
			int x;
			std::cin >> x;
			os += num1 * x;
			if (x & 1)num2 += num1, num1 = 0;
		}
		std::cout << os + es << "\n";
	}
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	int t;
	std::cin >> t;

	while (t--) {
		solve();
	}

	return 0;
}

 C. Traffic Light

一个字符串中字符分别代表红,绿,黄,给定一个字符代表当前红绿灯状态,问最大什么时候才能通行

思路:

2*字符串即两个周期涵盖了所有情况,找最大值就行了

#include <bits/stdc++.h>
#define int long long

void solve() {
	int n;
	char ch;
	std::cin >> n >> ch;
	std::string s;
	std::cin >> s;
	std::string t = s;
	t += s;
	int f = 0, ans = -1;
	for (int i = (int)t.size() - 1; i >= 0 ; i--) {
		if (t[i] == 'g') f = i;
		if (t[i] == ch) ans = std::max(ans, f - i);
	}
	std::cout << ans << "\n";
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	int t;
	std::cin >> t;

	while (t--) {
		solve();
	}

	return 0;
}

 D. Divisibility by 2^n

有若干个操作,a[i]*i,每个数最多被乘一次,最少多少次把数组的乘积和能被2^n整除

思路:

如果数组所有元素有至少n个2的因子数那么一定能被2^n整除,否则在1~n中找2因子的数量,贪心地去选因子数最大的。

#include <bits/stdc++.h>
#define int long long
#define lowbit(x) (x)&-(x)

void solve() {
	int n;
	std::cin >> n;
	std::vector<int> a(n);
	std::vector<int> d;
	int cnt = 0;
	for (int i = 0; i < n; i++) {
		std::cin >> a[i];
		int k = a[i];
		while (k % 2 == 0) {
			k /= 2;
			cnt++;
		}
		int p = i + 1;
		int m = 0;
		while (p % 2 == 0) {
			p /= 2;
			m++;
		}
		if (m) {
			d.emplace_back(m);
		}
	}
	if (cnt >= n) {
		std::cout << 0 << "\n";
		return;
	}
	std::sort(d.begin(), d.end(), std::greater<int>());
	int j = 0, ans = 0, f = n - cnt, len = d.size();
	while (j < len && f) {
		if (d[j] <= f) {
			ans++;
			f -= d[j];
		}
		j++;
	}
	if (f) std::cout << -1 << "\n";
	else std::cout << ans << "\n";
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	int t;
	std::cin >> t;

	while (t--) {
		solve();
	}

	return 0;
}

学过佬的代码(结合__builtin_ctz( ) 太细了!!):

#include <bits/stdc++.h>

void solve() {
	int n;
	std::cin >> n;
	std::vector<int> a(n);
	for (int j = 0; j < n; j++) {
		std::cin >> a[j];
	}
	std::vector<int> b(n), c(n);
	for (int j = 0; j < n; j++) {
		b[j] = __builtin_ctz(a[j]);
		c[j] = __builtin_ctz(j + 1);
	}
	int cnt = 0;
	for (int j = 0; j < n; j++) {
		cnt += b[j];
	}
	std::sort(c.begin(), c.end(), std::greater<int>());
	int ans = 0;
	for (int j = 0; j < n; j++) {
		if (cnt < n) {
			cnt += c[j];
			ans++;
		}
	}
	if (cnt < n) {
		std::cout << -1 << "\n";
	} else {
		std::cout << ans << "\n";
	}
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	int t;
	std::cin >> t;

	while (t--) {
		solve();
	}

	return 0;
}

 E1. Divisible Numbers (easy version)

a,b,c,d,找到一组x,y(a<x<=c,b<y<=d),使x*y能整除a*b

暴力枚举即可

#include <bits/stdc++.h>
#define int long long
#define lowbit(x) (x)&-(x)
void solve() {
	int a, b, c, d;
	std::cin >> a >> b >> c >> d;
	int cur = a * b;
	int i = a + 1;
	while (i <= c) {
		int k = cur / std::__gcd(cur, i);
		int j = (k + b - 1 + 1) / k * k;
		if (j > b && j <= d) {
			std::cout << i << " " << j << "\n";
			return ;
		}
		i++;
	}
	std::cout << "-1 -1\n";
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	int t;
	std::cin >> t;

	while (t--) {
		solve();
	}

	return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值