题目大意:给你一个长度为$n$的$01$串,一次操作定义为:选取$3$个等距的元素,使其$0$变$1$,$1$变$0$,要求在$\Big\lfloor \dfrac n 3\Big\rfloor+12$次操作内变为全$0$。输出是否可行以及方案

题解:skip1978的博客讲的十分详细。发现给的操作次数很少,基本上一次操作要使得$3$个元素变成$0$

对于区间$[l,r]$,若$a_l=0$,这一位不用翻转,缩小到区间$[l+1,r]$,这样$a_l,a_{l+1},a_{l+2}$有$4$中可能:

  1. $1,1,1:$翻转$a_l,a_{l+1},a_{l+2}$就可以使得这三位变$0$
  2. $1,0,1:$翻转$a_l,a_{l+2},a_{l+4}$就可以使得这三位变$0$
  3. $1,0,0:$翻转$a_l,a_{l+3},a_{l+6}$就可以使得这三位变$0$
  4. $1,1,0:$可以按相同方法收缩右端点,直到右端点也出现这样的情况
    • 若$l,r$奇偶性相同,可以翻转$a_l,a_{\frac{l+r}{2}},a_r$和$a_{l+1},a_{\frac{l+r}{2}},a_{r-1}$使得这六位变成$0$
    • 若$l,r$奇偶性不同,可以翻转$a_l,a_{\frac{l+r-1}{2}},a_{r-1}$和$a_{l+1},a_{\frac{l+r+1}{2}},a_r$使得这六位变成$0$

然后发现若区间长度大于等于$8$,一定可以翻转成$0$,并且所有合法的翻转只有$12$次,可以暴力枚举每一个操作是否使用即可

卡点:找到答案后忘记退出

C++ Code:

#include <cstdio>
#include <vector>
#define maxn 100010 int n, s[maxn];
struct Step {
int a, b, c;
inline Step() {}
inline Step(int __a, int __b, int __c) {a = __a, b = __b, c = __c;}
};
std::vector<Step> Ans;
bool find_ans = false; inline void reverse(int a, int b, int c) {
s[a] ^= 1, s[b] ^= 1, s[c] ^= 1;
Ans.push_back(Step(a, b, c));
}
inline void reverse(int a, int c) {
int b = a + c >> 1;
reverse(a, b, c);
} std::vector<std::pair<int, int> > V;
int tmp[maxn];
#define rev(x) tmp[x.first] ^= 1, tmp[x.first + x.second >> 1] ^= 1, tmp[x.second] ^= 1
inline bool end(int l, int r) {
for (int i = l; i <= r; i++) if (tmp[i]) return false;
return true;
}
void calc(int l, int r) {
for (int i = l; i <= r - 2; i++) {
for (int j = i + 2; j <= r; j += 2) {
V.push_back(std::make_pair(i, j));
}
}
int sz = V.size(), U = 1 << sz;
for (int i = 0; i < U; i++) {
for (int i = l; i <= r; i++) tmp[i] = s[i];
for (int j = 0; j < sz; j++) if (i & 1 << j) rev(V[j]);
if (end(l, r)) {
find_ans = true;
for (int j = 0; j < sz; j++) if (i & 1 << j) reverse(V[j].first, V[j].second);
return ;
}
}
} #define checkl(x, a, b, c) (s[x] == a && s[x + 1] == b && s[x + 2] == c)
#define work(l, r, L, R) {reverse(l, r), solve(L, R); return ;}
#define checkr(x, a, b, c) (s[x] == a && s[x - 1] == b && s[x - 2] == c)
void solve(int l, int r) {
if (r - l + 1 <= 8) {
while (r - l + 1 < 8 && l > 1) l--;
while (r - l + 1 < 8 && r < n) r++;
calc(l, r);
return ;
}
if (!s[l]) {solve(l + 1, r); return ;}
if (!s[r]) {solve(l, r - 1); return ;}
if (checkl(l, 1, 1, 1)) work(l, l + 2, l + 3, r);
if (checkl(l, 1, 0, 1)) work(l, l + 4, l + 3, r);
if (checkl(l, 1, 0, 0)) work(l, l + 6, l + 3, r);
if (checkr(r, 1, 1, 1)) work(r - 2, r, l, r - 3);
if (checkr(r, 1, 0, 1)) work(r - 4, r, l, r - 3);
if (checkr(r, 1, 0, 0)) work(r - 6, r, l, r - 3);
if (r - l & 1) {
reverse(l, r - 1), reverse(l + 1, r);
solve(l + 3, r - 3);
} else {
reverse(l, r), reverse(l + 1, r - 1);
solve(l + 3, r - 3);
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", s + i);
solve(1, n);
if (find_ans) {
puts("YES");
printf("%d\n", Ans.size());
for (std::vector<Step>::iterator it = Ans.begin(); it != Ans.end(); it++) {
printf("%d %d %d\n", it -> a, it -> b, it -> c);
}
} else puts("NO");
return 0;
}

  

[CF1031E]Triple Flips的更多相关文章

  1. Codeforces 1071 C - Triple Flips

    C - Triple Flips 思路: 小范围暴力 大范围递归构造 构造方法: solve(l, r) 表示使l 到 r 区间全变为0的方法 为了使反转次数小于等于n/3 + 12 我们只需要保证每 ...

  2. Codeforces1071C Triple Flips 【构造】【Four Russians】

    题目分析: 这种题目显然可以先考虑哪些无解.我们发现我们不考虑操作次数的时候,我们可以选择连续的三个进行异或操作. 这样我们总能使得一个序列转化为$000...000xy$的形式.换句话说,对于$00 ...

  3. Codeforces 1071C Triple Flips 构造

    原文链接 https://www.cnblogs.com/zhouzhendong/p/CF1071C.html 题目传送门 - CF1071C 题意 给定一个长度为 n 的 01 数列,限定你在 $ ...

  4. Technocup 2019 - Elimination Round 2

    http://codeforces.com/contest/1031 (如果感觉一道题对于自己是有难度的,不要后退,懂0%的时候敲一遍,边敲边想,懂30%的时候敲一遍,边敲边想,懂60%的时候敲一遍, ...

  5. Codeforces Round #517

    传送门 A. Cram Time 你有一本书,阅读第\(i\)页需要花费\(i\)的时间.你第一天有\(a\)的时间,第二天有\(b\)的时间,问你的总阅读页数的最大值. Input: 一行包含\(2 ...

  6. 山东省第七届ACM省赛------Triple Nim

    Triple Nim Time Limit: 2000MS Memory limit: 65536K 题目描述 Alice and Bob are always playing all kinds o ...

  7. hdu 3908 Triple(组合计数、容斥原理)

    Triple Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) Total Su ...

  8. Flips测试类(page43)

    测试用例:所用java类: StdOut,StdIn , Counter, StdRandom, public class Flips { public static void main(String ...

  9. hdu 5517 Triple(二维树状数组)

    Triple Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

随机推荐

  1. webBrowser 应用编程函数总结

    /*============================说明部分================================= 实现一下函数需包含头文件 #include <Winine ...

  2. phpstudy apache启动失败,80端口占用问题解决方案

    安装phpstydy,启动apache时,启动失败,提示80端口占用,需要将占用80端口的服务进程关闭 1.运行cmd, netstat -ano 找到80端口对应的pid  4 2.一般都是调用 h ...

  3. elasticsearch 5.x 系列之四(索引模板的使用,详细得不要不要的)

    1,首先看一下下面这个索引模板 curl -XPUT "master:9200/_template/template_1?pretty" -H 'Content-Type: app ...

  4. hadoop2.5.0 HA高可用配置

    hadoop2.5.0 HA配置 1.修改hadoop中的配置文件 进入/usr/local/src/hadoop-2.5.0-cdh5.3.6/etc/hadoop目录,修改hadoop-env.s ...

  5. print(__file__)返回<encoding error>的问题

    今天写了一下代码,本来是想得到当前文件的上面三层的目录的,结果返回的却是错误 import os import sys print(__file__) # 得到上上层目录的路径之后,加入到默认的环境变 ...

  6. spring boot打包问题

    java.lang.IllegalArgumentException: No auto configuration classes found in META-INF/spring.factories ...

  7. 生産管理(PP)

    伝票系 製造指図 マスタ系 生産資源/治工具 作業区 能力 作業手順 作業バージョン 作業記録 需要予測プロファイル 計画手配 MRP レシピ その他 カスタマイズ系 BOM関連 製造指図確認 伝票系 ...

  8. ABAP CDS ON HANA-(5)テーブル結合ビュー

    JOINs in CDS View In ABAP CDS, Join between two data sources is allowed. Allowed joins are:- Inner J ...

  9. python2.7练习小例子(二十四)

        24):1.题目:利用递归方法求5!.     程序分析:递归公式:fn=fn_1*4! #!/usr/bin/python # -*- coding: UTF-8 -*- def fact( ...

  10. python基础之socket套接字基础part2

    基于UDP的socket 面向无连接的不可靠数据传输,可以没有服务器端,只不过没有服务器端,发送的数据会被直接丢弃,并不能到达服务器端 1 #客户端 2 import socket 3 ip_port ...