zoukankan      html  css  js  c++  java
  • Codeforces1071C Triple Flips 【构造】【Four Russians】

    题目分析:

    这种题目显然可以先考虑哪些无解。我们发现我们不考虑操作次数的时候,我们可以选择连续的三个进行异或操作。

    这样我们总能使得一个序列转化为$000...000xy$的形式。换句话说,对于$000...0001$,$000...0010$,$000...0011$考虑无解条件即可。

    这时候写一个暴力程序,用$O(n^2*2^n)$的算法可以发现其中一个是总长小于$7$无解,另外两个是小于$8$无解。

    然后观察题目要求的操作次数与$n/3$有关,不难想到每$3$个分成一组,然后在组内调成$0$,允许利用组外信息,每组只允许用一次操作。但这样操作数会超过($011 or 110$)。

    那我们放宽一下限制,每$6$个分成一组,在组内调成$0$,允许利用组外信息,每组只允许操作两次。这样就可以了(我一开始以为$110111$是不行的,写了一个暴力后后来发现我脑残了)。

    这样我们考虑Four Russians,预处理出来每$6$组怎么走,最后对剩余的暴力就行了。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxn = 102000;
      5 
      6 int n,a[maxn],f[1<<12];
      7 struct node{int x,y,z;};
      8 vector <node> des[64];
      9 
     10 void init(){
     11     queue<int> q;
     12     int N = 6;
     13     memset(f,0x3f,sizeof(f));
     14     f[0] = 0; q.push(0);
     15     while(!q.empty()){
     16     int k = q.front();q.pop();
     17     for(int i=0;i<N;i++){
     18         if(f[k^(1<<i)] > f[k] + 1){
     19         for(int j=0;j<des[k].size();j++)
     20             des[k^(1<<i)].push_back(des[k][j]);
     21         des[k^(1<<i)].push_back((node){i,6,12-i});
     22         f[k^(1<<i)] = f[k]+1;
     23         q.push(k^(1<<i));
     24         }
     25         for(int j=i+1;j<N;j++){
     26         int z = (1<<i)+(1<<j);
     27         if(j+(j-i) < N) z |= (1<<2*j-i);
     28         if(f[k^z] > f[k]+1){
     29             for(int fr=0;fr<des[k].size();fr++)
     30             des[k^z].push_back(des[k][fr]);
     31             des[k^z].push_back((node){i,j,2*j-i});
     32             f[k^z] = f[k]+1;
     33             q.push(k^z);
     34         }
     35         }
     36     }
     37     }
     38 }
     39 
     40 node opt[maxn];
     41 int num;
     42 
     43 node lst[maxn];
     44 
     45 void Remain(){
     46     queue<int> q;
     47     memset(f,0x3f,sizeof(f));
     48     //for(int i=0;i<64;i++) des[i].clear();
     49     f[0] = 0;q.push(0);
     50     int N = min(n,12);
     51     while(!q.empty()){
     52     int k = q.front();q.pop();
     53     for(int i=0;i<N;i++){
     54         for(int j=i+1;j<N;j++){
     55         if(j+(j-i) >= N) break;
     56         int z = (1<<i)+(1<<j)+(1<<2*j-i);
     57         if(f[k^z] > f[k]+1){
     58             f[k^z] = f[k]+1;
     59             lst[k^z] = (node){i,j,2*j-i};
     60             q.push(k^z);
     61         }
     62         }
     63     }
     64     }
     65     int z = 0;
     66     for(int i=n-N+1;i<=n;i++){z = (z<<1)+a[i];}
     67     if(f[z] > 1e8){puts("NO");}
     68     else{
     69     puts("YES");
     70     printf("%d
    ",num+f[z]);
     71     for(int i=1;i<=num;i++){
     72         printf("%d %d %d
    ",opt[i].x,opt[i].y,opt[i].z);
     73     }
     74     while(z){
     75         printf("%d %d %d
    ",n-lst[z].z,n-lst[z].y,n-lst[z].x);
     76         int pp = z;
     77         z ^= (1<<lst[pp].x); z ^= (1<<lst[pp].y); z^= (1<<lst[pp].z);
     78     }
     79     }
     80 }
     81 
     82 void work(){
     83     for(int i=1;i<=n;i+=6){
     84     if(i+12 > n) break;
     85     int z = (a[i+5]<<5)+(a[i+4]<<4)+(a[i+3]<<3)+(a[i+2]<<2)+(a[i+1]<<1)+a[i];
     86     for(int j=0;j<des[z].size();j++){
     87         opt[++num] = des[z][j];
     88         opt[num].x += i; opt[num].y += i; opt[num].z += i;
     89         a[opt[num].x] ^= 1; a[opt[num].y] ^= 1; a[opt[num].z] ^= 1;
     90     }
     91     }
     92     Remain();
     93 }
     94 
     95 int main(){
     96     scanf("%d",&n);
     97     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
     98     init();
     99     work();
    100     return 0;
    101 }
  • 相关阅读:
    Jquery 公告 滚动+AJAX后台得到数据。
    图片上添加文字。
    javascript的window.onload与jquery的$(document).ready()
    后台JS写法
    Ajax xmlhttprequest原理(一)
    SQL语句二次排序。先根据是否置顶字段。再根据最后更新时间排序。
    引以为戒的SQL语句写法
    C#中var关键字怎么用 ~
    上传文件 解析
    简易公告
  • 原文地址:https://www.cnblogs.com/Menhera/p/9859073.html
Copyright © 2011-2022 走看看