洛谷 1312 [NOIP2011] Mayan游戏 dfs+模拟
来源:互联网 发布:西安网络写手招聘 编辑:程序博客网 时间:2024/06/11 22:12
题目:
https://www.luogu.org/problemnew/show/1312
早就想做了,现在才下定决心;
将近3个小时,终于做出来了;
第二个点跑了将近2s,吓~~
只要耐心,一点点想,一遍遍调,一切皆有可能 !
准备在洛谷上发一篇题解~~~~
优化:
1.如果存在一个格子的左边(右边)与它相同,不移动;
2.dfs时如果遇到空格直接break;
注意:
为保证字典序最小:
1.需要将图翻转90°;
2.某个格子只有在左边什么也没有时才向左移动;
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int ma[6][6][9];int n;int ans[20][20];bool vis[20][20],Mark[20][20];bool flag=0;int read()//没起到任何作用的手读;{ int ss=0; char c=getchar(); while(c<'0' || c>'9') c=getchar(); while(c>='0' && c<='9') { ss=ss*10+c-'0'; c=getchar(); } return ss;}void swap(int &x,int &y)//交换{ x^=y^=x^=y; return;}void copy(int i)//复制{ for(int j=0;j<7;j++) Mark[i][j]|=vis[i][j]; return;}void fall(int depth)//降落;{ for(int i=0;i<5;i++) { for(int j=0;j<7;j++) { if(!ma[depth][i][j]) continue; int x=i,y=j; while(y-1>=0 && !ma[depth][x][y-1] && ma[depth][x][y]) { swap(ma[depth][x][y-1],ma[depth][x][y]); y--; } } } return;}bool xiao(int depth){ bool f=0; int tot=0; memset(vis,0,sizeof(vis)),memset(Mark,0,sizeof(Mark)); for(int i=0;i<5;i++) { for(int j=0;j<7;j++) { if(Mark[i][j]) continue; if(!ma[depth][i][j]) break; tot=1,vis[i][j]=1; for(int v=1;v<=5;v++) { if(i+v<5) { if(ma[depth][i][j]==ma[depth][i+v][j])//横; tot++,vis[i+v][j]=1; else break; } } for(int v=-1;v>=-5;v--) { if(i+v>=0) { if(ma[depth][i][j]==ma[depth][i+v][j]) tot++,vis[i+v][j]=1; else break; } } if(tot>=3) { copy(i);//标记消除: f=1;//发生消除 } memset(vis,0,sizeof(vis));//初始化; vis[i][j]=1,tot=1; for(int v=1;v<=7;v++) { if(j+v<7) { if(ma[depth][i][j]==ma[depth][i][j+v])//纵; tot++,vis[i][j+v]=1; else break; } } for(int v=-1;v>=-7;v--) { if(j+v>=0) { if(ma[depth][i][j]==ma[depth][i][j+v]) tot++,vis[i][j+v]=1; else break; } } if(tot>=3) f=1,copy(i); memset(vis,0,sizeof(vis)); } } if(f)//发生过消除; { for(int i=0;i<5;i++) for(int j=0;j<7;j++) if(Mark[i][j]) ma[depth][i][j]=0; return true; } else return false;}bool check(){ for(int i=0;i<5;i++) if(ma[n][i][0]) return false; return true;}void dfs(int depth){ if(depth==n+1) { if(!check()) return;//如果没有消完; for(int i=1;i<=n;i++) { for(int j=1;j<=3;j++) printf("%d ",ans[i][j]); printf("\n"); } exit(0); } memcpy(ma[depth],ma[depth-1],sizeof(ma[depth-1]));//复制过来; for(int i=0;i<5;i++) { for(int j=0;j<7;j++) { if(!ma[depth][i][j]) break; int dir=0;//方向; if(!i || i==4) { if(i==0) dir=1;//第一列只能右移; else if(i==4 && !ma[depth][i-1][j]) dir=-1;//最后一列只能左移; if(ma[depth][i][j]!=ma[depth][i+dir][j]) { ans[depth][1]=i;//储存答案; ans[depth][2]=j; ans[depth][3]=dir; swap(ma[depth][i+dir][j],ma[depth][i][j]); do { fall(depth);//直到消不了为止; }while(xiao(depth)); dfs(depth+1); memcpy(ma[depth],ma[depth-1],sizeof(ma[depth-1]));//回溯: } else continue; } else if(i>0 && i<4) { dir=1; if(ma[depth][i][j]!=ma[depth][i+dir][j]) { ans[depth][1]=i,ans[depth][2]=j,ans[depth][3]=dir; swap(ma[depth][i+dir][j],ma[depth][i][j]); do{fall(depth);}while(xiao(depth)); dfs(depth+1); memcpy(ma[depth],ma[depth-1],sizeof(ma[depth-1])); } dir=-1; if(!ma[depth][i+dir][j]) { ans[depth][1]=i,ans[depth][2]=j,ans[depth][3]=dir; swap(ma[depth][i+dir][j],ma[depth][i][j]); do{fall(depth);}while(xiao(depth)); dfs(depth+1); memcpy(ma[depth],ma[depth-1],sizeof(ma[depth-1])); } } } } return;}void solve(){ scanf("%d",&n); for(int i=0;i<5;i++) { int tot=0,x; while(true) { x=read(); if(!x) break; ma[0][i][tot++]=x; } } dfs(1); cout<<"-1"<<endl; return;}int main(){ solve(); return 0;}
阅读全文
1 0
- 洛谷 1312 [NOIP2011] Mayan游戏 dfs+模拟
- noip2011 Mayan游戏 dfs+模拟
- 【NOIP2011】【DFS】Mayan游戏
- 【NOIP2011】洛谷1312 Mayan游戏
- #NOIP2011#Mayan游戏(Dfs搜索)
- 洛谷 P1312 [NOIP2011 D1T3] Mayan游戏
- [NOIP2011]Mayan游戏【搜索】
- NOIP2011 Mayan游戏(搜索)
- 【CodeVS1136】【NOIP2011】Mayan 游戏
- NOIP2011 Mayan游戏 题解
- 【NOIP2011】Mayan游戏 搜索
- NOIP2011 Mayan游戏
- NOIP2011【Mayan游戏】
- NOIP2011 Mayan游戏
- noip2011 Mayan游戏
- 【NOIP2011提高组T3】Mayan游戏-DFS剪枝
- noip2011 day1-3 Mayan游戏
- noip2011 mayan游戏 (深搜)
- bzoj 2342: [Shoi2011]双倍回文
- <差分约束>luogu 3275 糖果
- 蚯蚓 NOIP2016 提高组 Day2 T2
- UVa11468
- <Data Visualization>1 ggplot2 图形语法
- 洛谷 1312 [NOIP2011] Mayan游戏 dfs+模拟
- bzoj 2287 【POJ Challenge】消失之物 背包动规
- bzoj 3747 [POI2015]Kinoman 线段树
- 页表项标记位的理解
- 2017.10.29离线赛总结
- 【学习记录】传递闭包
- bzoj 2527 [Poi2011]Meteors 整体二分+树状数组
- [BZOJ1644][Usaco2007Oct]Obstacle Course 障碍训练课(spfa)
- 与自我投资相匹配的笔记法(笔记)