[NOIP2011] 玛雅游戏

solution:

正解是大暴搜

基本思路:将n步dfs出来暴力组合

剪枝:如果一个点的左边已经有点,就不需要在枚举这种情况,因为从左边那个点走过来更优

(ps:旁门左道 函数前加上 __attribute__((optimize("O3"))) )→_→

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<ctime>
  4 #include<queue>
  5 #include<algorithm>
  6 #include<iostream>
  7 #define dd double
  8 #define cop(a,b) memcpy(a,b,sizeof(a))
  9 #define mem(a,b) memset(a,b,sizeof(a))
 10 using namespace std;
 11 inline void swap(int &x,int &y){x^=y;y^=x;x^=y;}
 12 
 13 int n,u,o;
 14 int a[5][7];
 15 int ji[101][101],bushu;
 16 int flag;
 17 
 18 /*void out11()
 19 {
 20     printf("\n");
 21     for(int i=0;i<5;++i)
 22     {
 23         for(int j=0;j<7;++j)
 24           printf("%d ",a[i][j]);
 25         printf("\n");
 26     }
 27     printf("\n");
 28 }*/
 29 
 30 inline int check()
 31 {
 32     for(int i=0;i<5;++i)
 33       if(a[i][0])
 34         return 0;
 35     return 1;
 36 }
 37 
 38 inline void jilu(int x,int y,int val)
 39 {
 40     ji[++bushu][1]=x;
 41     ji[bushu][2]=y;
 42     ji[bushu][3]=val;
 43 }
 44 
 45 inline void print()
 46 {
 47     for(int i=1;i<=bushu;++i)
 48       printf("%d %d %d\n",ji[i][1],ji[i][2],ji[i][3]);
 49     flag=1;
 50     exit(0);
 51 }
 52 
 53 inline void fall()
 54 {
 55     int now;
 56     for(int i=0;i<5;++i)
 57         for(int j=0;j<7;++j)
 58           if(a[i][j])
 59           {
 60                 now=j;
 61                 while(now-1>=0&&!a[i][now-1])--now;
 62                 if(now!=j)swap(a[i][now],a[i][j]);
 63             }
 64 }
 65 
 66 inline int xiao()
 67 {
 68     int temp[5][7];
 69     cop(temp,a);
 70     int judge=0;
 71     for(int i=2;i<5;++i)
 72         for(int j=0;j<7;++j)
 73             if(a[i][j]&&a[i][j]==a[i-1][j]&&a[i][j]==a[i-2][j])
 74             {
 75               temp[i][j]=0;temp[i-1][j]=0;temp[i-2][j]=0;
 76               judge=1;
 77             }
 78     for(int j=2;j<7;++j)
 79       for(int i=0;i<5;++i)
 80             if(a[i][j]&&a[i][j]==a[i][j-1]&&a[i][j]==a[i][j-2])
 81             {
 82               temp[i][j]=0;temp[i][j-1]=0;temp[i][j-2]=0;
 83               judge=1;
 84             }
 85     cop(a,temp);
 86     return judge;
 87 }
 88 
 89 void dfs()
 90 {
 91     //printf("bushu=%d\n",bushu);
 92     //
 93     if(check())
 94       print();
 95     else
 96       if(n==bushu)
 97       {
 98             //printf("hhhhhh\n");
 99         return ;
100         }
101     for(int i=0;i<5;++i)
102         for(int j=0;j<7;++j)
103         {
104             if(!a[i][j])continue;
105             
106             int temp[5][7];
107             cop(temp,a);
108             
109             if(i!=4)
110             {
111                 jilu(i,j,1);
112                 swap(a[i][j],a[i+1][j]);
113                 while(1){fall();if(!xiao())break;}
114                 dfs();
115                 --bushu;
116                 cop(a,temp);
117             }
118         
119             if(i!=0&&!a[i-1][j])///******
120             {
121                 jilu(i,j,-1);
122                 swap(a[i][j],a[i-1][j]);
123                 while(1){fall();if(!xiao())break;}
124                 dfs();
125                 --bushu;
126                 cop(a,temp);
127             }
128             //dfs();
129             //cop(a,temp);
130         }
131 }
132 
133 int main(){
134     //freopen("1.tit","r",stdin);
135     //
136     //freopen("mayan8.in","r",stdin);
137     //freopen("2.txt","w",stdout);
138     scanf("%d",&n);
139     for(int i=0;i<5;++i)
140       for(int j=0;;++j)
141       {
142             cin>>a[i][j];
143             if(a[i][j]==0)break;
144             //out11();
145         }
146     
147     //out11();
148     
149     //cout<<0;
150     dfs();
151     
152     if(!flag)
153       printf("-1");
154     //while(1);
155     return 0;
156 }
code

 

posted @ 2017-07-27 21:02  A_LEAF  阅读(236)  评论(0编辑  收藏  举报