【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 ",ans[i][0]-1,ans[i][1]-1,ans[i][2]); 67 exit(0); 68 } 69 void search(int t){ 70 //printf("%d: ",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 }