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();
}