CF1458D Flip and Reverse 题解

思路#

由于它要求 01 数量相等,我们可以考虑站在前缀和的角度看待这个问题。

我们将 0 看作负一,1 看作一。

可以把它化成一个折线图(方便观察)。

观察一下它的操作实际上在干什么。

容易发现,在折线图上,我们把操作的 [l,r] 的整段折线 reverse 了一遍。

同样的,我们也就可以把前缀和数组相等的两个位置中间的一段进行 reverse。

这个操作其实是很强的。

由于我们不会改变前缀和数组。

那么我们可以对每一个前缀和建一张图。

  1. 初始变量 s=0
  2. 遇到一个 1,我们连一条 ss+1 的边,并让 s 加一。
  3. 遇到一个 0,我们连一条 ss1 的边,并让 s 减一。

我们可以发现,操作相当于我们可以可以从一个点出发,任意的跑一条回路。

只需要求一个字典序最小的欧拉回路即可。

Code#

#include <bits/stdc++.h>
using namespace std;

int n;
int a[1000010], *b;
string s;

inline void solve() {
  cin >> s;
  n = s.length();
  b = a + 500005;
  int c = 0;
  for (int i = 1; i <= n; i++) {
    if (s[i - 1] == '0') {
      c--;
      b[c]++;
    } else {
      b[c]++;
      c++;
    }
  }
  int d = 0;
  for (int i = 1; i <= n; i++) {
    if (!b[d] || (b[d - 1] >= 2)) {
      d--;
      b[d]--;
      cout << 0;
    } else {
      b[d]--;
      d++;
      cout << 1;
    }
  }
  cout << "\n";
}

int main() {
  int t;
  cin >> t;
  while (t--) solve();
}

作者:JiaY19

出处:https://www.cnblogs.com/JiaY19/p/18469098

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   JiaY19  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示