【noip2011】Mayan游戏
2013-10-22 23:50
309 查看
题解:
刷了一天的noip啊 做了10题! 突然找回了做马拉松的感觉- -
我中午竟然放弃治疗去看视频 做到晚上累得都快挂了 用电脑放一些rock 把音乐当咖啡硬撑下来 但是还是没能刷3届
唉 显然速度刷题是很容易忘的 简单写一些题解 然后睡觉去(- -。zZ)
赤裸裸的搜索 但是要加一些剪枝
1.如果交换的两个方块颜色相同则不换
2.如果移动时是向左且左边有方块则不动(左边的往右效果一样)
3.如果任意颜色发方块个数为1或2 显然无解return
我只加了这些剪枝速度貌似还不错 vijos上1300ms左右
关键是很多人说这题很复杂 - -?
其实思路清楚就不会(表示半小时搞定) 我感觉做这题就像在做游戏一样
可以写两个函数fall 和clean做掉落和清除 然后在要调用的地方写函数就会觉得清晰多了
代码:
View Code
刷了一天的noip啊 做了10题! 突然找回了做马拉松的感觉- -
我中午竟然放弃治疗去看视频 做到晚上累得都快挂了 用电脑放一些rock 把音乐当咖啡硬撑下来 但是还是没能刷3届
唉 显然速度刷题是很容易忘的 简单写一些题解 然后睡觉去(- -。zZ)
赤裸裸的搜索 但是要加一些剪枝
1.如果交换的两个方块颜色相同则不换
2.如果移动时是向左且左边有方块则不动(左边的往右效果一样)
3.如果任意颜色发方块个数为1或2 显然无解return
我只加了这些剪枝速度貌似还不错 vijos上1300ms左右
关键是很多人说这题很复杂 - -?
其实思路清楚就不会(表示半小时搞定) 我感觉做这题就像在做游戏一样
可以写两个函数fall 和clean做掉落和清除 然后在要调用的地方写函数就会觉得清晰多了
代码:
#include <cstdio> #include <cstdlib> struct info{ int a[7][9]; void print(){ for (int i=7;i>=1;i--){ for (int j=1;j<=5;j++) printf("%d ",a[j][i]); puts(""); } puts(""); } }now,save[6]; int n,rem[11],srem[6][11],ans[6][3],bo[7][9]; void swap(int &a,int &b){ int x=a; a=b,b=x; } void fall(){ for (int i=1;i<=5;i++) for (int j=2;j<=7;j++) if (!now.a[i][j-1] && now.a[i][j]){ int k; for (k=j-1;!now.a[i][k] && k>=1;--k); ++k; swap(now.a[i][j],now.a[i][k]); } } void markbo(){ for (int i=1;i<=5;i++) for (int j=1;j<=8;j++) if (now.a[i][j]){ if (now.a[i-1][j]==now.a[i][j] && now.a[i+1][j]==now.a[i][j]){ bo[i-1][j]=1; bo[i][j]=1; bo[i+1][j]=1; } if (now.a[i][j-1]==now.a[i][j] && now.a[i][j+1]==now.a[i][j]){ bo[i][j-1]=1; bo[i][j]=1; bo[i][j+1]=1; } } } bool clean(){ markbo(); int res=0; for (int i=1;i<=5;i++) for (int j=1;now.a[i][j] && j<=8;j++) if (bo[i][j]){ res=1; bo[i][j]=0; --rem[now.a[i][j]]; now.a[i][j]=0; } return res; } int work(int x,int y,int z){ swap(now.a[x][y],now.a[x+z][y]); fall(); while (clean()) fall(); int res=0; for (int i=1;i<=10;i++) if (rem[i]) if (!res || res>rem[i]) res=rem[i]; return res; } void print(){ for (int i=1;i<=n;i++) printf("%d %d %d\n",ans[i][0]-1,ans[i][1]-1,ans[i][2]); exit(0); } void search(int t){ //printf("%d:\n",t); //now.print(); save[t]=now; for (int i=1;i<=10;i++) srem[t][i]=rem[i]; for (int i=1;i<=5;i++) for (int j=1;now.a[i][j] && j<=7;j++) for (int k=1;k>=-1;k-=2) if (i+k>0 && i+k<=5){ if ((k==-1 && now.a[i-1][j]) || now.a[i][j]==now.a[i+k][j]) continue; ans[t][0]=i,ans[t][1]=j,ans[t][2]=k; int x=work(i,j,k); if (t==n){ if (x==0) print(); }else if (x>2) search(t+1); now=save[t]; for (int l=1;l<=10;l++) rem[l]=srem[t][l]; } } int main(){ scanf("%d",&n); for (int x,i=1;i<=5;i++) while (scanf("%d",&x),x){ now.a[i][++now.a[i][0]]=x; ++rem[x]; } for (int i=1;i<=5;i++) now.a[i][0]=0; search(1); puts("-1"); }
View Code
相关文章推荐
- 【搜索】【NOIP2011提高组Day1】Mayan游戏
- [NOIP2011]Mayan游戏 题解
- [NOIP2011] day1铺地毯,选择客栈,Mayan游戏
- noip2011 Mayan游戏
- 【NOIP2011提高组T3】Mayan游戏-DFS剪枝
- NOIP 2011 Mayan游戏
- NOIP 2011 Senior 3 - Mayan游戏
- [NOIP 2011] Mayan游戏
- 【NOIP2011】洛谷1312 Mayan游戏
- NOIP2011 Mayan游戏
- 【搜索】【NOIP2011提高组Day1】Mayan游戏
- NOIP2011复赛提高组day1(A:铺地毯 B:选择客栈 C:mayan游戏)
- NOIP2011(DAY1)解题报告(C/C++)(铺地毯)(选择客栈)(Mayan 游戏)
- 【NOIP2011】Mayan游戏 搜索
- NOIP2011 mayan游戏 解题报告(搜索)
- noip2011 Mayan游戏
- 【NOIP2011】【DFS】Mayan游戏
- 【NOIP 2011】Mayan游戏
- 猥琐的暴搜 NOIP2011 Mayan游戏