Codeforces Round 970 (Div. 3) ABCDEFGH
来源:Codeforces Round 970 (Div. 3)
- 头文件
#include <bits/stdc++.h>
using namespace std;
#define YES "YES"
#define NO "NO"
#define Yes "Yes"
#define No "No"
#define F first
#define S second
#define int long long
#define ull unsigned long long
#define endl "\n"
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define rep(i, j, k) for (int i = (j); i < (k); i++)
#define all(x) x.begin(), x.end()
#define vi vector<int>
#define pii pair<int, int>
A. Sakurako's Exam#
思路#
看1能不能来抵消2,如果没有1就看2的数量,有1就看是奇数还是偶数,如果是偶数就能抵消2
代码#
string solve() {
int a, b;
cin >> a >> b;
if (a == 0) {
if (b % 2 == 0)
return YES;
else
return NO;
}
if (a % 2 == 1) {
return NO;
} else {
return YES;
}
}
signed main() {
IOS;
int t = 1;
cin >> t;
while (t--) {
cout << solve() << endl;
}
return 0;
}
B. Square or Not#
思路#
先看长度符不符合要求
再特判一下有没有0的情况,除n=4外其他没有0都输出No
然后根据n求边长,枚举所有点
代码#
string s;
string solve() {
int n;
cin >> n >> s;
if ((int)sqrt(n) * (int)sqrt(n) != n) {
return No;
}
if (s.find('0') == string::npos) {
if (n == 4)
return Yes;
else
return No;
}
int a = (int)sqrt(n);
for (int i = 0; i < a; i++) {
for (int j = 0; j < a; j++) {
char ch = s[i * a + j];
char sch;// 应该是1或0
if (i == 0 || j == 0 || i == a - 1 || j == a - 1)
sch = '1';
else
sch = '0';
if (ch != sch) {// 实际与理论比较一下
return No;
}
}
}
return Yes;
}
signed main() {
IOS;
int t = 1;
cin >> t;
while (t--) {
cout << solve() << endl;
}
return 0;
}
C. Longest Good Array#
思路#
最优情况就是从
然后开头到结尾的就相差
代码#
const int N = 5e4;
int f[N];
int solve() {
int l, r;
cin >> l >> r;
int len = r - l + 1;
int ans = lower_bound(f, f + N, len) - f;
return ans;
}
void pre() {
f[0] = 0;
f[1] = 1;
for (int i = 2; i < N; i++) f[i] = f[i - 1] + i;
}
signed main() {
IOS;
int t = 1;
pre();
cin >> t;
while (t--) {
cout << solve() << endl;
}
return 0;
}
D. Sakurako's Hobby#
思路#
并查集,因为是全排列,就是好几个圈圈,一开始还以为会出现环上带线,那就麻烦了
代码#
const int N = 2e5 + 10;
string s;
int fa[N];
int ans[N];
// 并查集
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void merge(int x, int y) {
fa[find(x)] = find(y);
}
void solve() {
int n;
cin >> n;
rep(i, 1, n + 1) {
fa[i] = i;
ans[i] = 0;
}
rep(i, 1, n + 1) {
int tmp;
cin >> tmp;
merge(i, tmp);
}
cin >> s;
rep(i, 0, n) {
// s的0表示黑色
if (s[i] == '0') ans[find(fa[i + 1])]++;
}
rep(i, 1, n + 1) cout << ans[find(fa[i])] << " ";
cout << endl;
}
E. Alternating String#
思路#
如果是偶数就把奇数上最多的保留,偶数位上最多的字母保留
如果是奇数,就维护前缀和,然后遍历每个位置
删除当前位置后
如果想算奇数上的
把奇数和偶数上的最大数算出来,再跟目前的最大数比较,和较大的更优
代码#
int n;
string s;
const int N = 2e5 + 10;
int sum[26][2][N];// sum[i][j][k] 从0到k位,奇(1)/偶(0)位上字母i的数量
int solve() {
cin >> n >> s;
if (n % 2 == 0) {// 不删,算数量就行
map<int, int> ji_mp;
map<int, int> ou_mp;
for (int i = 0; i < n; i += 2) ou_mp[s[i] - 'a']++;
for (int i = 1; i < n; i += 2) ji_mp[s[i] - 'a']++;
int ji_mx = 0;
int ou_mx = 0;
for (int i = 0; i < 26; i++) {
ji_mx = max(ji_mx, ji_mp[i]);
ou_mx = max(ou_mx, ou_mp[i]);
}
return n - ji_mx - ou_mx;
}
// 初始化
rep(i, 0, 26) {
rep(j, 0, n + 2) {
sum[i][0][j] = 0;
sum[i][1][j] = 0;
}
}
// 算累加
for (int i = 0; i < n; i++) {
if (i % 2 == 0)
sum[s[i] - 'a'][0][i + 1] = 1;
else
sum[s[i] - 'a'][1][i + 1] = 1;
for (int j = 0; j < 26; j++) {
sum[j][0][i + 1] += sum[j][0][i];
sum[j][1][i + 1] += sum[j][1][i];
}
}
int ji_mx = 0;
int ou_mx = 0;
for (int i = 1; i <= n; i++) {
int tjimx = 0, toumx = 0;
// 求最大
for (int j = 0; j < 26; j++) {
int ji_num = sum[j][1][i - 1] + (sum[j][0][n] - sum[j][0][i]);
int ou_num = sum[j][0][i - 1] + (sum[j][1][n] - sum[j][1][i]);
tjimx = max(tjimx, ji_num);
toumx = max(toumx, ou_num);
}
// 比较当前位置的最大和总的最大
if (tjimx + toumx > ji_mx + ou_mx) {
ji_mx = tjimx;
ou_mx = toumx;
}
}
return n - 1 - ji_mx - ou_mx + 1;
}
F. Sakurako's Box#
思路#
以
然后总共抽
代码#
// int用long long来替,避免溢出
const int MOD = 1e9 + 7;
const int N = 2e5 + 10;
int ksm(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}
int sum[N]; // 后缀和
int a[N];
int solve() {
int n;
cin >> n;
rep(i, 1, n + 1) {
cin >> sum[i];
a[i] = sum[i];
}
for (int i = n - 1; i >= 1; i--) {
sum[i] += sum[i + 1];
sum[i] %= MOD;
}
int s = 0;
rep(i, 1, n) {
int tmp = (a[i] * sum[i + 1]) % MOD;
s = (s + tmp) % MOD;
}
int k = ((n - 1) * n / 2) % MOD;
if (s % k == 0) return s / k;
return (ksm(k, MOD - 2) * s) % MOD;
}
G. Sakurako's Task#
思路#
加来减去这种题,很可能跟gcd有关系,
首先分析一下,所有数的gcd一定小于等于最小值,比如gcd=2时,n=5,那么一定可以通过这个2把数组变成
特判一下n=1的情况
代码#
int n, k;
int a[200005];
int solve() {
cin >> n >> k;
rep(i, 1, n + 1) cin >> a[i];
if (n == 1) {
if (k <= a[1])
return k - 1;
else
return k;
}
// 求所有的gcd
int GCD = 0;
rep(i, 1, n + 1) GCD = __gcd(GCD, a[i]);
// 如果k很大
if ((n - 1) * (GCD - 1) < k) return n - 1 + k;
int re = (k - 1) / (GCD - 1); // region
/*
如gcd=3时,数组是[0,3,6,9] ,k=1或2,位于0到3之间,k=4或5,位于3到6之间
相当于位于区域0和区域1,每个区域大小是gcd-1
*/
return re * GCD + (k - 1) % (GCD - 1) + 1;
}
H. Sakurako's Test#
思路#
最小中位数,就是把所有值都尽量缩小,那就所有值取%x
二分答案,答案一定在0到x之间
每次check查看比mid小的值的数量,如果数量过多说明mid过大,需要减小,反之需要增加
以下是需要注意的:
- 这个二分,有时候是r-1,l+1,有时候又不用,所以我一般是记录答案,如果mid跟答案一样就break,基本没问题,也不用反复尝试
- 这个check,如果每次遍历,经过亲身经历,会超时,所以需要记录数量,然后把每个%x后比mid小的区间加上,就是需要一个前缀和来加速
- 本题会重复询问同一个值,需要记忆化答案
代码#
int cnt[200010];
int n;
bool check(int mid, int q) {
int small = 0;
small += cnt[mid - 1];
for (int i = 1; 1; i++) {
if (mid - 1 + q * i >= n) {
if (i * q - 1 <= n) small += cnt[n] - cnt[i * q - 1];
break;
}
small += cnt[mid - 1 + q * i] - cnt[i * q - 1];
}
if (small <= n / 2)
return true;
else
return false;
}
int t;
pii ans[100001];// 记忆化答案
void solve() {
int m;
cin >> n >> m;
rep(i, 0, n + 1) cnt[i] = 0;
rep(i, 0, n) {
int x;
cin >> x;
cnt[x]++;
}
rep(i, 1, n + 1) cnt[i] += cnt[i - 1];
rep(i, 0, m) {
int q;
cin >> q;
if (ans[q].F == t) {
cout << ans[q].S << " ";
continue;
}
int l = 0, r = q;
int mid;
int res = 0;
while (l < r) {
mid = (l + r) / 2;
if (check(mid, q)) {// 不需要思考,莽上去就行
if (res == mid) break;
res = mid;
l = mid;
} else {
r = mid;
}
}
cout << res << " ";
ans[q] = {t, res};
}
cout << endl;
}
signed main() {
IOS;
for (int i = 0; i < 100001; i++) {
ans[i] = {-1, -1};
}
cin >> t;
while (t--) solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步