原文链接 https://www.cnblogs.com/zhouzhendong/p/CF1071C.html

题目传送门 - CF1071C

题意

  给定一个长度为 n 的 01 数列,限定你在 $\left \lfloor \frac n 3 \right \rfloor +12$ 次操作内将所有的数字都变成 0 。

  操作定义为:选择三个数 $x,y,z(x<y<z, y-x=z-y)$ ,使得 a[x],a[y],a[z] 翻转 (0 变 1 ,1 变 0)

  如果不能完成,那么输出 NO ,否则输出 YES 并输出方案。

  $n\leq 10^5$

题解

  首先我们很容易找到一个可以将一个 1 变成 0 的操作:

0 0 0 0 0 0 1
1 0 0 1 0 0 0
1 1 1 0 0 0 0
0 0 0 0 0 0 0

  

  然后考虑如何高效简化局面。

  假设当前局面中只有区间 [L,R] 中有 1 。我们需要以平均每次将区间压缩 3 单位长度的效率来操作。

  接下来就是分类讨论:

  1.  a[L]=0  直接 L++

  2.  a[R]=0  直接 R--

  3.  a[L]=a[L+1]=a[L+2]=1  直接翻转他们,消耗一次操作,效率为 3 。

  4.  a[R]=a[R-1]=a[R-2]=1  同理,效率为 3 。

  5.  a[L]=1,a[L+1]=0  找到 a[L] 之后的第一个 1 ,假设位置为 p ,并使得 x=L,y=p,z=2p-L,消耗一次操作,效率 至少为 3 。

  6.  a[R]=1,a[R-1]=0  类似于第 5 种。

(后面那个是没用的,因为数据水,所以比赛的时候直接可以过,为了想这个续了我好久qaq)

  7.  a[L]=a[L+1]=a[R]=a[R-1]=1,a[L+2]=0,a[R-2]=0  这个是最难想到的。

      如果 (L+R) mod  2 = 0 ,设 m = (L+R)/2 ,那么消耗两次操作:(L,m,R) 和 (L+1,m,R-1)

      如果 (L+R) mod  2 = 1 ,设 m = (L+R-1)/2 ,那么消耗两次操作:(L,m,R-1) 和 (L+1,m+1,R)

      这样做两步,由于 a[L+2]=a[R-2]=0,所以至少效率为 3 。

  保证效率为 3 之后。最终我们要面对的是小范围情况。

  我们现在只有 2 个 1 了。我们首先要把他们移到一起。这个很容易。

  然后将他们转化成一个 1 然后变成 0 就好了。

  我们还要注意一种特殊情况:

0 0 0 0 0 0 1 1

  我们不能鲁莽地把后面两个 1 变成一个 1 放到第 6 个位置上,这样显然不行,应该直接做两次 1 变成 0 的操作。

  当然具体实现的时候还需要注意许多细节问题。我的代码写的比较丑。

  另外,这里再提供 1 组 hack 数据。这是我对着某分十分短的AC代码学习之后马上造出来的hack数据。


代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100005;
LL read(){
LL x=0,f=1;
char ch=getchar();
while (!isdigit(ch)&&ch!='-')
ch=getchar();
if (ch=='-')
f=-1,ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+ch-48,ch=getchar();
return x*f;
}
int n;
int a[N];
int m=0;
struct Perf{
int x,y,z;
Perf(){}
Perf(int _x,int _y,int _z){
x=_x,y=_y,z=_z;
}
}p[N];
int find(int x,int dx){
while (!a[x]&&1<=x&&x<=n)
x+=dx;
return x;
}
void pef(int x,int y,int z){
a[x]^=1,a[y]^=1,a[z]^=1;
p[++m]=Perf(x,y,z);
}
int gettot(){
int tot=0;
for (int i=1;i<=n;i++)
tot+=a[i];
return tot;
}
void del(int x){
pef(x-6,x-3,x);
pef(x-5,x-4,x-3);
pef(x-6,x-5,x-4);
}
int main(){
n=read();
for (int i=1;i<=n;i++)
a[i]=read();
int L=1,R=n;
while (L+2<=R){
if (a[L]&&a[L+1]&&a[L+2]){
pef(L,L+1,L+2);
L+=3;
continue;
}
if (a[R]&&a[R-1]&&a[R-2]){
pef(R-2,R-1,R);
a[R-2]=a[R-1]=a[R]=0;
R-=3;
}
if (!a[L]){
L++;
continue;
}
if (!a[R]){
R--;
continue;
}
int l=find(L+1,1);
int r=find(R-1,-1);
if (l==R)
break;
if (l!=L+1&&2*l-L<=R){
pef(L,l,l*2-L);
continue;
}
else if (r!=R-1&&2*r-R>=L){
pef(2*r-R,r,R);
continue;
}
else if (l==L+1&&r==R-1){
if ((R-L)%2==0){
int m=(L+R)/2;
pef(L,m,R);
pef(L+1,m,R-1);
continue;
}
else {
int m1=(L+R)/2,m2=m1+1;
pef(L,m1,R-1);
pef(L+1,m2,R);
continue;
}
}
else if (l==L+1&&2*r-R>=L){
pef(2*r-R,r,R);
continue;
}
else if (r==R-1&&2*l-L<=R){
pef(L,l,l*2-L);
continue;
}
else if (l==L+1)
pef(L,l,l+1);
else if (r==R-1)
pef(r-1,r,R);
else
break;
}
if (gettot()>0){
int l=find(1,1);
int r=find(n,-1);
if (l!=r){
while (r+3<=min(9,n)){
pef(r,r+1,r+2);
pef(r+1,r+2,r+3);
r+=3;
}
while (l+3<=min(9,n)){
pef(l,l+1,l+2);
pef(l+1,l+2,l+3);
l+=3;
}
if (gettot()){
if (l>=7&&r>=7){
del(l);
del(r);
}
else {
if ((l+r)%2==0)
return puts("NO"),0;
if (l+1!=r)
pef(l+1,(l+r+1)/2,r);
if (l+2<=n)
pef(l,l+1,l+2),l=r=l+2;
else
pef(l-1,l,l+1),l=r=l-1;
}
}
}
if (gettot()){
while (l+3<=min(9,n)){
pef(l,l+1,l+2);
pef(l+1,l+2,l+3);
l+=3;
}
if (l<7)
return puts("NO"),0;
del(l);
}
}
puts("YES");
printf("%d\n",m);
for (int i=1;i<=m;i++)
printf("%d %d %d\n",p[i].x,p[i].y,p[i].z);
return 0;
}

  

Codeforces 1071C 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 1383D - Rearrange(构造)

    Codeforces 题面传送门 & 洛谷题面传送门 一道不算困难的构造,花了一节英语课把它搞出来了,题解简单写写吧( 考虑从大往小加数,显然第三个条件可以被翻译为,每次加入一个元素,如果它所 ...

  4. Codeforces 549B. Looksery Party[构造]

    B. Looksery Party time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  5. codeforces 323A. Black-and-White Cube 构造

    输入n 1 <= n <= 100 有一个n * n * n 的立方体,由n ^ 3 个1 * 1 * 1 的单位立方体构成 要用white 和 black 2种颜色来染这n ^ 3个立方 ...

  6. Codeforces Gym 100531I Instruction 构造

    Problem I. Instruction 题目连接: http://codeforces.com/gym/100531/attachments Description Ingrid is a he ...

  7. codeforces 22C System Administrator(构造水题)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud System Administrator Bob got a job as a s ...

  8. Codeforces 353D Queue(构造法)

    [题目链接] http://codeforces.com/contest/353/problem/D [题目大意] 10^6个男女排队,每一秒,如果男生在女生前面,即pos[i]是男生,pos[i+1 ...

  9. Codeforces 482 - Diverse Permutation 构造题

    这是一道蛮基础的构造题. - k         +(k - 1)      -(k - 2) 1 + k ,    1 ,         k ,             2,    ....... ...

随机推荐

  1. 前端 -----02 body标签中相关标签

    今日内容: 字体标签: h1~h6.<font>.<u>.<b>.<strong><em>.<sup>.<sub> ...

  2. 【原创】大数据基础之Hive(4)hive元数据库核心表结构

    1 dbs +-------+-----------------------+----------------------------------------------+------------+- ...

  3. java结合testng,利用yaml做数据源的数据驱动实例

    testng的功能很强大,利用@DataProvider可以做数据驱动,数据源文件可以是EXCEL,XML,YAML,甚至可以是TXT文本.在这以yaml为例: 备注:@DataProvider的返回 ...

  4. which命令和bin目录

    命令: which 作用: 查看执行命令所在位置 使用: which ls which useradd 等等... bin和sbin: 绝大多数可执行文件都保存在 /bin./sbin./usr/bi ...

  5. 如何用Axure快速制作APP交互原型

    对于产品经理来说,熟练使用一些常用软件是一项十分必要的技能.其中,作为一个专业的快速原型设计工具,Axure RP无疑在产品人心中拥有一个难以撼动的地位.但就要PS一样,虽然足够专业,但同样也会存在使 ...

  6. hadoop 透明加密

    hadoop 透明加密 hadoop 透明加密 kms transparent 2015年04月09日 18:12:20 糖糖_ 阅读数:12248 标签: transparenthadoop kms ...

  7. C语言学习及应用笔记之三:C语言const关键字及其使用

    在C语言程序中,const关键字也是经常会用到的一个关键字,那么使用const关键字的目的是什么呢?事实上,在程序中使用const关键字的主要目的就是为了向使用者传递设计者的一些意图. 事实上,无论我 ...

  8. Confluence 6 系统运行信息中的 JVM 内存使用情况

    当前一个正在运行的 Confluence 6 实例的内存使用情况 https://www.cwiki.us/display/CONF6ZH/Viewing+System+Information

  9. 【batch】批处理文件多参数处理和for循环字符串连接

    batch文件写起来,酸爽不谈了.[1]今天在github上发现个好东西batsh,运行地址:https://batsh.org/.[1] 这里需求的场景是:调用run.bat脚本并传入多个参数(相对 ...

  10. 对<tr><td>标签里的input 循环取值

    需求描述:单击table整行,跳转到具体的信息页面  关键就是获取整行的id,传给后台做查询,返回list 解决思路:用带参数函数传过去id,然后在js的函数中用$("#id"). ...