【模拟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
原文地址:https://www.cnblogs.com/Wwb123/p/11167641.html