【noip2011】Mayan游戏

题解:

刷了一天的noip啊 做了10题! 突然找回了做马拉松的感觉- -

我中午竟然放弃治疗去看视频 做到晚上累得都快挂了 用电脑放一些rock 把音乐当咖啡硬撑下来 但是还是没能刷3届

唉 显然速度刷题是很容易忘的 简单写一些题解 然后睡觉去(- -。zZ)

 

赤裸裸的搜索 但是要加一些剪枝

1.如果交换的两个方块颜色相同则不换

2.如果移动时是向左且左边有方块则不动(左边的往右效果一样)

3.如果任意颜色发方块个数为1或2 显然无解return

我只加了这些剪枝速度貌似还不错 vijos上1300ms左右

关键是很多人说这题很复杂 - -?

其实思路清楚就不会(表示半小时搞定) 我感觉做这题就像在做游戏一样

可以写两个函数fall 和clean做掉落和清除 然后在要调用的地方写函数就会觉得清晰多了

 

代码:

 1 #include <cstdio>
 2 #include <cstdlib>
 3 struct info{
 4     int a[7][9];
 5     void print(){
 6         for (int i=7;i>=1;i--){
 7             for (int j=1;j<=5;j++) printf("%d ",a[j][i]);
 8             puts("");
 9         }
10         puts("");
11     }
12 }now,save[6];
13 int n,rem[11],srem[6][11],ans[6][3],bo[7][9];
14 void swap(int &a,int &b){ int x=a; a=b,b=x; }
15 void fall(){
16     for (int i=1;i<=5;i++)
17     for (int j=2;j<=7;j++)
18     if (!now.a[i][j-1] && now.a[i][j]){
19         int k;
20         for (k=j-1;!now.a[i][k] && k>=1;--k);
21         ++k;
22         swap(now.a[i][j],now.a[i][k]);
23     }
24 }
25 void markbo(){
26     for (int i=1;i<=5;i++)
27     for (int j=1;j<=8;j++)
28     if (now.a[i][j]){
29         if (now.a[i-1][j]==now.a[i][j] && now.a[i+1][j]==now.a[i][j]){
30             bo[i-1][j]=1;
31             bo[i][j]=1;
32             bo[i+1][j]=1;
33         }
34         if (now.a[i][j-1]==now.a[i][j] && now.a[i][j+1]==now.a[i][j]){
35             bo[i][j-1]=1;
36             bo[i][j]=1;
37             bo[i][j+1]=1;
38         }
39     }
40 }
41 bool clean(){
42     markbo();
43     int res=0;
44     for (int i=1;i<=5;i++)
45     for (int j=1;now.a[i][j] && j<=8;j++)
46     if (bo[i][j]){
47         res=1;
48         bo[i][j]=0;
49         --rem[now.a[i][j]];
50         now.a[i][j]=0;
51     }
52     return res;
53 }
54 int work(int x,int y,int z){
55     swap(now.a[x][y],now.a[x+z][y]);
56     fall();
57     while (clean()) fall();
58     int res=0;
59     for (int i=1;i<=10;i++)
60     if (rem[i])
61     if (!res || res>rem[i]) res=rem[i];
62     return res;
63 }
64 void print(){
65     for (int i=1;i<=n;i++)
66     printf("%d %d %d\n",ans[i][0]-1,ans[i][1]-1,ans[i][2]);
67     exit(0);
68 }
69 void search(int t){
70     //printf("%d:\n",t);
71     //now.print();
72     save[t]=now;
73     for (int i=1;i<=10;i++) srem[t][i]=rem[i];
74     for (int i=1;i<=5;i++)
75     for (int j=1;now.a[i][j] && j<=7;j++)
76     for (int k=1;k>=-1;k-=2)
77     if (i+k>0 && i+k<=5){
78         if ((k==-1 && now.a[i-1][j]) || now.a[i][j]==now.a[i+k][j]) continue;
79         ans[t][0]=i,ans[t][1]=j,ans[t][2]=k;
80         int x=work(i,j,k);
81         if (t==n){
82             if (x==0) print();
83         }else if (x>2) search(t+1);
84         now=save[t];
85         for (int l=1;l<=10;l++) rem[l]=srem[t][l];
86     }
87 }
88 int main(){
89     scanf("%d",&n);
90     for (int x,i=1;i<=5;i++)
91     while (scanf("%d",&x),x){
92         now.a[i][++now.a[i][0]]=x;
93         ++rem[x];
94     }
95     for (int i=1;i<=5;i++) now.a[i][0]=0;
96     search(1);
97     puts("-1");
98 }
View Code

 

posted @ 2013-10-22 23:50  g_word  阅读(327)  评论(0编辑  收藏  举报