Codeforces Round #826 (Div. 3) A - E

A

照着题意if else即可。

void solve() {
string s1, s2; cin >> s1 >> s2;
int n = sz(s1), m = sz(s2);
if (s1 == s2) cout << '=' << endl;
else {
if (s1[n - 1] > s2[m - 1]) cout << '<' << endl;
else if (s2[m - 1] > s1[n - 1]) cout << '>' << endl;
else if (s1[n - 1] == 'S'){
if (n > m) cout << "<" <<endl;
else if (n < m) cout << ">" << endl;
else cout << "=\n";
}
else if (s1[n - 1] == 'L'){
if (n > m) cout << ">" <<endl;
else if (n < m) cout << "<" << endl;
else cout << "=\n";
}
}
}

B

n=3之外,可以把数组分为长度大于n/2和小于n/2的前后两段,调换顺序输出。

void solve() {
int n; cin >> n;
if (n == 3) cout << -1 << endl;
else {
int mid = n / 2 + 1;
for (int i = mid;i <= n;i++) cout << i << ' ';
for (int i = 1;i < mid;i++) cout << i << ' ';
cout << endl;
}
}

C

可以枚举第一段的和为多少,然后双指针做后面的分段,时间复杂度O(n2),赛时写了个先枚举最大段长度,再枚举第一段长度的,好像是个O(n3),但跑得很快过了。

void solve() {
int n; cin >> n;
vector<int> a(n + 1), sum(n + 1);
for (int i = 1;i <= n;i++) {
cin >> a[i];
sum[i] = sum[i - 1] + a[i];
}
for (int len = 1;len <= n;len ++) {
bool ok = false;
for (int i = 1;i <= len;i++) {
int res = sum[i];
for (int l = i + 1, r = i + 1;l <= n;l ++) {
while (sum[r] - sum[l - 1] < res && r - l + 1 <= len) r ++;
if (sum[r] - sum[l - 1] != res || r - l + 1 > len) break;
else {
l = r;
r = r + 1;
if (l == n) ok = true;
}
}
if (ok) break;
}
if (ok) {
cout << len << endl;
return ;
}
}
cout << n << endl;
}

D

根据完全二叉树最后一层有n个节点,则总共的节点数量为n21个,建出完全二叉树。(虚空建图了,其实根本不需要写建树过程)
接下来从叶子结点向上遍历,记录左右子树的最大值和最小值,如果左子树的最大值大于右子树的最大值,则需要一次交换,且需要满足minval=maxval+1

也可以用线段树做,这里完全二叉树也可以看做是一颗线段树,做的过程就是用左右子树的信息更新父亲结点的信息,和线段树build类似。

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
void solve() {
int n, m; cin >> n; m = n * 2 - 1;
vector<int> a(n + 1);
for (int i = 1;i <= n;i++) cin >> a[i];
if (n == 1) {
cout << 0 << endl;
return;
}
bool ok = true;
vector<int> g[m + 1], mx(m + 1), mi(m + 1), ans(m + 1);
for (int i = m;i > 1;i--) {
int p = i / 2;
g[p].push_back(i);
} //发现后面没有用到
function<void(int x)> dfs = [&](int x) {
int l = x * 2, r = x * 2 + 1;
if (r <= m) {
dfs(l); dfs(r);
ans[x] = ans[l] + ans[r];
mx[x] = max(mx[l], mx[r]);
mi[x] = min(mi[l], mi[r]);
if (mx[l] > mx[r] && mx[r] + 1 != mi[l]) ok = false;
if (mi[r] < mi[l] && mx[r] + 1 != mi[l]) ok = false;
if (mx[l] < mx[r] && mx[l] + 1 != mi[r]) ok = false;
if (mi[l] == mx[r] + 1) ans[x] ++;
}
else mx[x] = mi[x] = a[x - n + 1];
};
dfs(1);
if (!ok) cout << "-1\n";
else cout << ans[1] << endl;
}
signed main(void) {
cin.tie(nullptr), cout.tie(nullptr) -> ios::sync_with_stdio(false);
int t = 1;
cin >> t;
while (t --) solve();
return 0;
}

E

不够分奴,想过是dp,但是没仔细想怎么转移。

dpi=true/false表示前i个数是否满足条件。
对所有的1in有转移方程:
iai1>=0,dpi|=dpiai1
i+ai<=n,dpi+ai|=dpi1

int dp[200010];
void solve() {
int n; cin >> n;
vector<int> a(n + 1), pre[n + 1];
memset(dp, 0, sizeof dp);
for (int i = 1;i <= n;i++) cin >> a[i];
dp[0] = 1;
for (int i = 1;i <= n;i++) {
if (i - a[i] - 1 >= 0) dp[i] |= dp[i - a[i] - 1];
if (i + a[i] <= n) dp[i + a[i]] |= dp[i - 1];
}
cout << (dp[n] == 1 ? "YES\n" : "NO\n");
}

F

待补

G

待补

posted @   Coldarra  阅读(65)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示