当前位置: 首页 > news >正文

【题解】Codeforces Round 1019 (Div. 2) B.Binary Typewriter ~ E.Keep the Sum

B.Binary Typewriter

在这里插入图片描述

思路

  • 至多使用1次操作,考虑1次操作的效果。
  • 发现,1次操作可以使得0和1更连贯,减少切换0/1导致的操作数
  • 最多减少两次操作

AC代码

#include<bits/stdc++.h>
#define int long longusing namespace std;
typedef pair<int,int> PII;
void solve()
{int n;string s;cin >> n >> s;s = "0" + s;bool op = 0;int ans = 0;for(int i = 1; i <= n; i ++){if(op != s[i] - '0'){op = !op;ans ++;}ans ++;}int j1 = -1;for(int i = 1; i <= n; i ++){if(s[i] == '1'){j1 = i;break;}}if(j1 != -1){int j2 = -1;for(int i = j1 + 1; i <= n; i ++){if(s[i] == '0'){j2 = i;break;}}if(j2 != -1){ans --;int j3 = -1;for(int i = j2 + 1; i <= n; i ++){if(s[i] == '1'){j3 = i;break;}}if(j3 != -1){ans --;}}}cout << ans << '\n';}signed main()
{ios::sync_with_stdio(false);cin.tie(0);int t = 1;cin >> t;while(t --) solve();
}

C.Median Splits

在这里插入图片描述

思路

  • 可以数列中把小于等于k的数统统记为-1,因为彼此没有区别,无论是k - 1,k - 2,还是k - 100,在计算中位数时效果相同。同理,大于k的记作1。这样操作以后,整个新数列的和如果小于等于 0, 则原数列中位数小于等于k。(这是中位数常用技巧)

  • 题目给出的中位数式子是嵌套的,要满足外层中位数<=k,需要内层至少有2个中位数 <= k。

  • 将数列的三段简称为,前段,中段,后段,分类讨论三种情况,前+后,前+中,中+后。

  • 前+后,贪心,找到满足的中位数<=k的最短前缀和最短后缀,二者不重叠(至少相隔一个)则符合

  • 前+中,先找到最短前缀,在由有最短前缀后一位出发找第二段满足条件的,找得到即有解。注意,如果a1 <= k且 a2 >= k,前缀需要包括下a2,即取第一段为[a1,a2]

  • 中+后 同 前+中,改成后缀即可

AC代码

#include<bits/stdc++.h>
#define int long longusing namespace std;
typedef pair<int,int> PII;
void solve()
{int n,k;cin >> n >> k;vector<int> a(n+1);for(int i = 1; i <= n; i ++) cin >> a[i];vector<int> b(n+1);for(int i = 1; i <= n; i ++){if(a[i] <= k) b[i] = -1;else b[i] = 1;}int l = -1,r = -1,sum = 0;for(int i = 1; i <= n; i ++){sum += b[i];if(sum <= 0){l = i;break;}}sum = 0;for(int i = n; i >= 1; i --){sum += b[i];if(sum <= 0){r = i;break;}}if(l != -1 && r != -1 && l + 1 < r){cout << "YES\n";return;}if(l != -1){sum = 0;if(l == 1 && n >= 2 && b[l] == -1 && b[l+1] == 1) l ++;for(int i = l + 1; i <= n - 1; i ++){sum += b[i];if(sum <= 0){cout << "YES\n";return;}}}if(r != -1){sum = 0;if(r == n && n >= 2 && b[r] == -1 && b[r-1] == 1) r --;for(int i = r - 1; i >= 2; i --){sum += b[i];if(sum <= 0){cout << "YES\n";return;}}}cout << "NO\n";
}signed main()
{ios::sync_with_stdio(false);cin.tie(0);int t = 1;cin >> t;while(t --) solve();
}

D.Local Construction

在这里插入图片描述

思路

  • 最后一个留下的数已知,正难则反,从倒数第一次删除往前考虑
  • 定义非大位置,为不满足 ai > ai-1 和 ai > ai+1的下标i,即是被删除的位置,非小位置则相反。
  • 不考虑第一个位置和最后一个位置,如果第 i 次删除的是非大位置,往 pj = i 的地方填入小值或许满足条件,发现填入,比已经敲定的值都小的值,且新填入的值按顺序递减可以满足题意。例如下图,空心点表示已经敲定的值,删除的就是,黑色实心点。
  • 为了避免第一个位置和最后一个位置出现问题,可以把前半部分的递减改为递增,同样符合
    在这里插入图片描述

AC代码

#include<bits/stdc++.h>
#define int long longusing namespace std;
typedef pair<int,int> PII;
void solve()
{int n;cin >> n;int mx = -1;vector<int> a(n+1);for(int i = 1; i <= n; i ++) cin >> a[i];vector<vector<int>> v(40);int init = -1;for(int i = 1; i <= n; i ++){mx = max(a[i],mx);if(a[i] == -1) init = i;else v[a[i]].push_back(i);}vector<int> ans(n+1),st(n+1);st[init] = 1;int up = 0,down = 0;for(int j = mx; j >= 1; j --){vector<int> tmp;if(j % 2 == 1){for(auto i : v[j]){if(i > init) ans[i] = ++up;else tmp.push_back(i);}reverse(tmp.begin(),tmp.end());for(auto i : tmp){ans[i] = ++up;}}else{for(auto i : v[j]){if(i > init)ans[i] = --down;else tmp.push_back(i);}reverse(tmp.begin(),tmp.end());for(int i : tmp){ans[i] = --down;}}}int mi = 1e9;for(int i = 1; i <= n; i ++){mi = min(ans[i],mi);}for(int i = 1; i <= n; i ++){ans[i] += -mi + 1;cout << ans[i] << " \n"[i == n];}}signed main()
{ios::sync_with_stdio(false);cin.tie(0);int t = 1;cin >> t;while(t --) solve();
}

E. Keep the Sum

在这里插入图片描述

注:思维构造题,难度大,赛时仅4人通过

思路

  • 题目要求满足 ai + aj == k才可以操作,该条件苛刻。如果一对满足的i,j都没有,直接判断原序列是否非减即可
  • 反之,则找到了一对 i, j 满足条件。
  • 由于条件苛刻,考虑能否使得操作之后,仍然有数对满足条件,从而进一步操作。
  • 如果 ai + aj == k,那么可以交换 i / j和任意元素, 假定交换x位置的元素,那么先令ai -= ai - ax,aj += ai - ax,具体操作命令为 “i j a[i]-a[x]“,此时ax + aj == k ,再令 ax -= ax - 原ai ,aj += ax - 原ai ,则完成了i与x的交换,具体操作命令为 “x j 原a[i]-a[x]”
  • 那么,首先将 找到的满足条件的 i j 分别换到第一个和最后一个位置。然后将 ai 操作至0,aj操作至k,那么,所有为 0 的数都可以换到数组最前面,为 k的数都可以换到数组最后面,形成排好序的前缀,后缀。
  • 下一步,再将前缀的最后一个位置调整至 1,后缀的第一个位置调整为 k - 1,可以处理 1 和 k - 1。 重复直至 k/2和k/2 + 1。
  • 由于k较大,可以忽略数列了没有的数。

AC代码

#include<bits/stdc++.h>
#define int long longusing namespace std;
const int mod = 998244353;
typedef pair<int,int> PII;
void solve()
{int n,k;cin >> n >> k;vector<int> a(n+1);for(int i = 1; i <= n; i ++) cin >> a[i];map<int,int> mp;int x1 = -1,y1 = -1;for(int i = 1; i <= n; i ++){if(mp.find(k - a[i]) != mp.end()){x1 = mp[k-a[i]],y1 = i;break;}mp[a[i]] = i;}if(x1 == -1 && y1 == -1){for(int i = 1; i <= n - 1; i ++){if(a[i] > a[i+1]) {cout << -1 << '\n';return;}}cout << 0 << '\n';return;}vector<tuple<int,int,int>> ans;auto swap = [&](int l,int r,int x) -> void{if(l == r){return;}int tmp = a[r];ans.push_back({r,x,a[r] - a[l]});a[x] += a[r] - a[l];a[r] -= a[r] - a[l];ans.push_back({l,x,a[l]-tmp});a[x] += a[l] - tmp;a[l] -= a[l] - tmp;};swap(1,x1,y1);swap(n,y1,1);set<PII> s;for(int i = 2; i <= n - 1; i ++){s.insert({a[i],i});}int j1 = 1,j2 = n;while(s.size()){auto [l,id1] = *s.begin();auto [r,id2] = *s.rbegin();if(l - 0 < k - r){ans.push_back({j1,j2,a[j1] - l});a[j2] += a[j1] - l;a[j1] -= a[j1] - l;}else{ans.push_back({j2,j1,a[j2] - r});a[j1] += a[j2] - r;a[j2] -= a[j2] - r;}while(s.size() && (*s.begin()).first == a[j1]){auto tmp = *s.begin();j1 ++;s.erase({a[j1],j1});s.insert({a[j1],tmp.second});s.erase(s.begin());swap(j1,tmp.second,j2);}while(s.size() && (*s.rbegin()).first == a[j2]){auto tmp = *s.rbegin();j2 --;s.erase({a[j2],j2});s.insert({a[j2],tmp.second});s.erase(--s.end());swap(j2,tmp.second,j1);}}cout << ans.size() << '\n';for(auto &[x,y,z] : ans){cout << x << ' ' << y << ' ' << z << '\n';}
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);int t = 1;cin >> t;while(t --) solve();return 0;
}

相关文章:

  • 【赵渝强老师】使用TiDB的审计日志
  • Learning vtkjs之ImageStreamline
  • URP - 公告牌的效果实现
  • 运维仙途 第2章 日志深渊识异常
  • 《多端统一的终极答案:X5内核增强版的渲染优化全解析》
  • AI赋能烟草工艺革命:虫情监测步入智能化时代
  • 栈与队列 Part 6
  • AI HR新范式:易路iBuilder如何通过“技术隐身,价值凸显”,成为HR身份转型的好帮手
  • 消防岗位技能竞赛流程方案策划
  • 【CUDA pytorch】
  • 基于连接感知的实时困倦分类图神经网络
  • kibana重建es索引
  • ShardingSphere5详细笔记
  • OpenCV-Python (官方)中文教程(部分一)_Day20
  • 软件架构选型之“如何选”
  • 生物化学笔记:神经生物学概论05 感受野 视觉中枢 高级视皮层中的信息走向
  • 【python实用小脚本-43】用Python自动发送生日祝福,让情感更高效
  • 希尔伯特第十问题:是一个伪命题
  • 时态--00--总述
  • 代码随想录打卡|Day31动态规划(最后一块石头的重量2、目标和、一和零)
  • 上海:以税务支持鼓励探索更多的创新,助力企业出海
  • 奈雪的茶叫停“能喝奶茶就不要喝水”宣传,当地市监称不要误导消费者
  • 山西太原小区爆炸事故已造成17人受伤
  • 医学统计专家童新元逝世,终年61岁
  • 蔡澜回应“入ICU观察”称未至于病危,助理:只是老毛病
  • 量子传感新技术“攻克”退相干难题