zoukankan      html  css  js  c++  java
  • 【模拟7.10】排序(搜索+剪枝)

     考试时没想出正解,最后打了个暴力骗分,暴力还好.....就是搜索每个状态,然后暴力枚举,以后如果有时间还是要打

    正解的,但我太蒟蒻了,打不出来......

    然后就是正解也是搜索

    首先明白一条性质

            不管是怎样的操作,只要每种操作都确定下,不管怎样改变次序,都不会改变结果。

           (关于证明,可以自己把每个位置想象成一个块,每次移动块也随之移动,不管次序结果相同。)

    然后此题可以分为四个情况

    设搜索中的区间长度为2^k,so当前要将2^(k-1)的区间都搞成递增的;

    当此时不符合递增条件的有一个2^k区间,就将它内部互换

    当两个时,就需要分四种情况交叉呼唤(这时最好不要用数组存储要操作的块数,因为搜完后会回溯)

    当无时直接搜索下一个

    当太多时return反正也改不完。

    代码:

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<cstring>
      6 #include<vector>
      7 #include<string>
      8 #define MAXN 21000
      9 #define pt printf("---------
    ");
     10 using namespace std;
     11 int tot;
     12 bool bian[MAXN];
     13 int base[MAXN];int n;
     14 int a[MAXN];
     15 int jie[MAXN];
     16 void qian(int k,int x,int y)//2^k长的段 第x段 第y段
     17 {
     18     int star=(x-1)*base[k]+1;
     19     int la=x*base[k];
     20     for(int i=star;i<=la;++i)
     21     {
     22        swap(a[i],a[i+(y-x)*base[k]]);
     23     }
     24 }
     25 int sum;
     26 vector<int>wr;vector<int>ci;
     27 int work(int kx,int xx,int yy,int cc1,int cc2)
     28 {
     29         qian(kx-1,xx,yy);
     30         int star_1=(cc1-1)*base[kx]+base[kx-1];
     31         int star_2=(cc2-1)*base[kx]+base[kx-1];
     32         //printf("2————搜索 a[%d]=%d a[%d]=%d wr0%d wr1=%d %d
    ",star_1,a[star_1],star_2,a[star_2],xx,yy,kx+1);
     33         if(a[star_1]+1!=a[star_1+1]||a[star_2]+1!=a[star_2+1])
     34         {
     35                 qian(kx-1,xx,yy);
     36                 return 0;
     37         }
     38         return 1;
     39 }
     40 void DFS(int kx,int cnt)//搜索长度为2^k区间 然后用了cnt个操作
     41 {
     42     if(kx>n)
     43     {
     44         for(int i=1;i<=base[n];++i)
     45         {if(a[i-1]+1!=a[i]) return ;}
     46         sum+=jie[cnt];
     47        // printf("sum=%d cnt=%d
    ",sum,cnt);
     48         return ;
     49     }
     50    // printf("kx=%d cnt=%d
    ",kx,cnt);
     51     int duan=base[n-kx];
     52     wr.clear();ci.clear();
     53     for(int k=1;k<=duan;++k)
     54     {
     55         int star=(k-1)*base[kx]+base[kx-1];//   ([][*]|[*][])
     56         if(a[star]+1!=a[star+1])
     57         {
     58     //        printf("第%d段 a[%d]=%d a[%d]=%d duan=%d %d
    ",k,star,a[star],star+1,a[star+1],k*2-1,k*2);
     59             wr.push_back(k*2-1);
     60             wr.push_back(k*2);
     61             ci.push_back(k);
     62         }
     63     }
     64     if(wr.size()>4)
     65     {
     66        return ;
     67     }
     68     if(wr.size()==2)
     69     {
     70         qian(kx-1,wr[0],wr[1]);
     71         int star=(ci[0]-1)*base[kx]+base[kx-1];
     72         if(a[star]+1!=a[star+1])
     73         {  
     74             qian(kx-1,wr[0],wr[1]);
     75             return ;
     76         }
     77         else
     78         {
     79             int xx=wr[0],yy=wr[1];
     80      //       printf("1————搜索 a[%d]=%d a[%d]=%d wr0%d wr1=%d %d
    ",star,a[star],star+1,a[star+1],wr[0],wr[1],kx+1);
     81             DFS(kx+1,cnt+1);
     82             qian(kx-1,xx,yy);
     83         }
     84     }
     85     if(wr.size()==4)
     86     {
     87          int xx1=wr[0],xx2=wr[1],yy1=wr[2],yy2=wr[3];
     88          int cc1=ci[0];int cc2=ci[1];
     89          if(work(kx,xx1,yy1,cc1,cc2)==1)
     90          {
     91              DFS(kx+1,cnt+1);
     92              qian(kx-1,xx1,yy1);
     93     //         printf("2----%d %d
    ",xx1,yy1);
     94          }
     95          if(work(kx,xx1,yy2,cc1,cc2)==1)
     96          {
     97              DFS(kx+1,cnt+1);
     98              qian(kx-1,xx1,yy2);
     99    //          printf("2----%d %d
    ",xx1,yy2);        
    100          }
    101          if(work(kx,xx2,yy1,cc1,cc2)==1)
    102          {
    103             DFS(kx+1,cnt+1);
    104             qian(kx-1,xx2,yy1);
    105     //        printf("2----%d %d
    ",xx2,yy1);   
    106          }
    107          if(work(kx,xx2,yy2,cc1,cc2)==1)
    108          {
    109             DFS(kx+1,cnt+1);
    110             qian(kx-1,xx2,yy2);
    111    //         printf("2----%d %d
    ",xx2,yy2);   
    112          }
    113     }
    114     if(wr.size()==0)
    115     {
    116         DFS(kx+1,cnt);
    117     }
    118     return ;
    119 }
    120 int main()
    121 {
    122      scanf("%d",&n);
    123      base[0]=1;jie[0]=1;
    124      for(int i=1;i<=n;++i)
    125      {
    126         base[i]=base[i-1]*2;jie[i]=jie[i-1]*i;
    127      } 
    128      for(int i=1;i<=base[n];++i)
    129      {
    130         scanf("%d",&a[i]);
    131      }
    132      DFS(1,0);
    133      printf("%d
    ",sum);
    134 }
    View Code
  • 相关阅读:
    Android | 教你如何开发一键银行卡绑定功能
    Android | 教你如何开发一个拍照翻译小程序
    Android | 教你如何开发一个证件照DIY小程序
    Android | 教你如何用三十分钟在安卓上开发一个微笑抓拍神器
    设计之禅——备忘录模式
    设计之禅——中介者模式
    设计之禅——解释器模式(译文)
    设计之禅——享元模式
    设计之禅——责任链模式
    设计之禅——桥接模式
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11167641.html
Copyright © 2011-2022 走看看