CF1999 Codeforces Round 964 (Div. 4)

Codeforces Round 964 (Div. 4)

A+B Again?

入门题,题目保证数字一定是两位数,所以就非常简单。

#include <bits/stdc++.h>
#define int long long
 
using namespace std;
const int maxn = 2e5 + 10;
 
void solve() {
	int n;
	cin >> n;
	cout << n % 10 + n / 10 << '\n';
}
 
signed main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int t;
	cin >> t;
	//t = 1;
	while (t--) solve();
}

Card Game

交了很多发,最后才发现正解。两局中我方获得两胜或者一胜一平都是可以赢的。最后答案乘 2 2 2 即可,因为我方先翻 a a a b b b 都是一样的结果。

#include <bits/stdc++.h>
#define int long long
 
using namespace std;
const int maxn = 2e5 + 10;
 
void solve() {
	int a, b, c, d;
	cin >> a >> b >> c >> d;
	int ans = 0;
	if (a > c && b >= d) ans++;
	if (a == c && b > d) ans++;
	if (a > d && b >= c) ans++;
	if (a == d && b > c) ans++;
	cout << ans * 2 << '\n';
}
 
signed main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int t;
	cin >> t;
	//t = 1;
	while (t--) solve();
}

Showering

题意:

给你长度为 m m m 的序列,求是否能在 n n n 个区间使用后,剩下的空区间是否还剩余长度为 s s s 的空区间。

思路:

一眼贪心,将区间按照左端点排序。从左向右扫一遍,若其中有合法区间或者头和尾有合法区间则可行,否则不行。

#include <bits/stdc++.h>
#define int long long
 
using namespace std;
const int maxn = 2e5 + 10;
 
struct node {
	int x, y;
	bool operator < (const node &o) const {return x < o.x;}
}a[maxn];
 
int n, s, m, f;

void solve() {
	cin >> n >> s >> m;
	for (int i = 1; i <= n; ++i) cin >> a[i].x >> a[i].y;
	sort(a + 1, a + n + 1);
	f = 0;
	for (int i = 1; i < n; ++i)
		if (a[i + 1].x - a[i].y >= s) f = 1;
	if (m - a[n].y >= s) f = 1;
	if (a[1].x >= s) f = 1;
	cout << (f ? "YES" : "NO") << '\n';
}
 
signed main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int t;
	cin >> t;
	//t = 1;
	while (t--) solve();
}

Slavic’s Exam

分两种情况,要么字符串 t t t 已经是 s s s 的子序列,要么在字符串 s s s 中从前往后扫一遍求出答案,其中,如果两个数字不能匹配就往后用 ‘?’ 替代。

#include <bits/stdc++.h>
#define int long long
 
using namespace std;
const int maxn = 2e5 + 10;
 
string a, b;
 
void solve() {
	cin >> a >> b;
	int n = a.size(), m = b.size();
	for (int i = 0, j = 0; i < n && j < m; ++i) {
		if (a[i] == '?') {
			a[i] = b[j];
			j++;
		} else if (a[i] == b[j]) j++;
		if (j == m) {
			cout << "YES\n"; 
			for (int i = 0; i < n; ++i) if (a[i] == '?') a[i] = 'a';
			cout << a << '\n';
			return;
		}
	}
	cout << "NO\n";
}
 
signed main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int t;
	cin >> t;
	//t = 1;
	while (t--) solve();
}

Triple Operations

题意:

给定区间 [ l , r ] [l,r] [l,r],每次操作在其中选两个数字 x x x y y y,将其分别变为 x × 3 x \times 3 x×3 ⌊ y 3 ⌋ \lfloor \dfrac{y}{3} \rfloor 3y。求最少的操作数量使所有数字变成 0 0 0

思路:

考虑贪心,先把最小的 l l l l + 1 l+1 l+1 操作 ⌊ ( log ⁡ 3 l ) ⌋ \lfloor(\log_3l)\rfloor ⌊(log3l)⌋ 次后变成 0 0 0,在重复执行一轮使得 l + 1 l+1 l+1 变回原来的数值。然后,我们将 l ( 0 ) l(0) l(0) 与每个数字进行操作使其变为 0 0 0,总共做的操作数就是 2 × ⌊ ( log ⁡ 3 l ) ⌋ + ∑ i = l + 1 r ⌊ ( log ⁡ 3 i ) ⌋ 2\times \lfloor(\log_3l)\rfloor+ \sum_{i=l+1}^r \lfloor(\log_3i)\rfloor 2×⌊(log3l)⌋+i=l+1r⌊(log3i)⌋,我们预处理出值域中每一个数字的 log ⁡ 3 \log_3 log3 值,便可以 O ( 1 ) O(1) O(1) 进行操作了。

#include <bits/stdc++.h>
#define int long long
 
using namespace std;
const int maxn = 2e5 + 10;
 
int l, r;
int lg[maxn], s[maxn];
 
int ccc(int x) {
	int res = 0;
	while (x) {
		x /= 3;
		res++;
	}
	return res;
}
 
int calc(int l, int r) {
	int res = 0;
	res += (lg[r] - lg[l - 1]);
	return res;
}
 
void solve() {
	cin >> l >> r;
	cout << (lg[l] - lg[l - 1]) * 2 + calc(l + 1, r) << '\n';
}
 
void init() {
	for (int i = 0; i < maxn; ++i) lg[i] = lg[i - 1] + ccc(i);
}
 
signed main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	init();
	int t;
	cin >> t;
	//t = 1;
	while (t--) solve();
}

Expected Median

#include <bits/stdc++.h>
#define int long long
 
using namespace std;
const int maxn = 2e5 + 10, mod = 1e9 + 7;
 
int n, k;
int a[maxn];
 
 
int fac[maxn], inv[maxn];
 
int quickMod(int a,int b) {
	int ans = 1;
	while (b) {
		if (b & 1)
			ans = ans * a % mod;
		a = a*a % mod;
		b >>= 1;
	}
	return ans;
}
 
void getFac() {
	fac[0] = inv[0] = 1;
	for (int i = 1 ; i <= (maxn - 5); i++) {
		fac[i] = fac[i-1] * i % mod;
		inv[i] = quickMod(fac[i],mod-2);
	}
}
 
int C(int n,int m) {
	return fac[n] * inv[n-m] % mod * inv[m] % mod;
}
 
void solve() {
	cin >> n >> k;
	int t1 = 0, t0 = 0;
	for (int i = 1, x; i <= n; ++i) {
		cin >> x;
		if (x == 0) t0++;
		else t1++;
	}
	int ans = 0;
	for (int i = max(k - t0, k / 2 + 1); i <= min(k, t1); ++i) {
		ans = (ans + C(t1, i) * C(t0, k - i) % mod + mod) % mod;
	}
	cout << ans << '\n';
}
 
signed main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	getFac();
	int t;
	cin >> t;
	//t = 1;
	while (t--) solve();
}

Ruler (easy version)

#include <bits/stdc++.h>
#define int long long
 
using namespace std;
 
void solve() {
	int l = 2, r = 999, res = 0, x;
	while (l <= r) {
		int mid = l + r >> 1;
		cout << "? " << mid << " " << mid << endl;
		cin >> x;
		if ((mid + 1) * (mid + 1) == x) r = mid - 1, res = mid;
		else l = mid + 1;
	}
	cout << "! " << res << endl;
}
 
signed main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int t;
	cin >> t;
	while (t--) solve();
}

Ruler (hard version)

#include <bits/stdc++.h>
#define int long long
 
using namespace std;
 
int query(int x, int y) {
	cout << "? " << x << ' ' << y << endl;
	int res = 0;
	cin >> res;
	return res;
}
 
void solve() {
	int l = 1, r = 999, k;
	while (l + 1 < r) {
		int x = l + (r - l) / 3;
		int y = l + (r - l) * 2 / 3;
		k = query(x, y);
		if (x * y == k) l = y;
		else if (x * (y + 1) == k) l = x, r = y;
		else r = x;
	}
	cout << "! " << r << endl;
}
 
signed main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int t;
	cin >> t;
	while (t--) solve();
}

  • 30
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值