noip2011提高组——mayan游戏
2015-02-08 10:12
357 查看
这道题看了 除了暴力dfs +模拟 真的找不到其他思路了
再一看 dfs深度最多才5 棋盘7 *5 业界良心。。
而且格子也只有左右移动
暴力dfs 就是干。。。
当然纯暴力当然不行的 不然怎么做noipday1压轴题啊、、
一定要剪枝
因为向右移动优先于向左移动
我只剪了一个枝 就是当 一个格子向左移动的时候 如果左边有一个值 就pass掉
因为这个格子向左移 等于 上一个格子向右移 重复了O(∩_∩)O~
还要注意 这个题一般的dfs回溯(通过纯递归)
是行不通的 因为这过程中有消除和掉落的操作 执行了之后就无法回到上一步
所以要么用结构体数组 储存状态(这种要把结构体数组开大点 免得状态太多爆掉)
或者是用栈结构(这个比较省空间 我用的栈)实现dfs
好了 剪了枝就是看dfs+模拟能力和 代码能力了。。。
有一个坑了我很久的是 在设置“掉下”这个操作的时候
掉下到了0就要特判了 我开始没有 特判 出现了负数下标 就程序崩溃 乱赋值了。。。QAQ
再一看 dfs深度最多才5 棋盘7 *5 业界良心。。
而且格子也只有左右移动
暴力dfs 就是干。。。
当然纯暴力当然不行的 不然怎么做noipday1压轴题啊、、
一定要剪枝
因为向右移动优先于向左移动
我只剪了一个枝 就是当 一个格子向左移动的时候 如果左边有一个值 就pass掉
因为这个格子向左移 等于 上一个格子向右移 重复了O(∩_∩)O~
还要注意 这个题一般的dfs回溯(通过纯递归)
是行不通的 因为这过程中有消除和掉落的操作 执行了之后就无法回到上一步
所以要么用结构体数组 储存状态(这种要把结构体数组开大点 免得状态太多爆掉)
或者是用栈结构(这个比较省空间 我用的栈)实现dfs
好了 剪了枝就是看dfs+模拟能力和 代码能力了。。。
有一个坑了我很久的是 在设置“掉下”这个操作的时候
掉下到了0就要特判了 我开始没有 特判 出现了负数下标 就程序崩溃 乱赋值了。。。QAQ
#include<iostream> #include<cstdio> #include<stack> #include<algorithm> #include<cstring> using namespace std; int n; int now; int mac; struct state { int col[11]; int step; int map[5][7]; int stepx[6]; int stepy[6]; int cz[6]; }cs,ns,start; stack<state>s; void readdata() { scanf("%d",&n); for(int i=0;i<=4;i++) for(int j=0;j<=7;j++) { scanf("%d",&cs.map[i][j]); if(cs.map[i][j]==0) break; cs.col[cs.map[i][j]]++; mac=max(mac,cs.map[i][j]); } } void deal() { int lef=0; for(int i=1;i<=mac;i++) lef+=ns.col[i]; if(lef!=0) return; for(int i=1;i<=n;i++) printf("%d %d %d\n",ns.stepx[i],ns.stepy[i],ns.cz[i]); exit(0); } bool drop() { bool ret=false; for(int i=0;i<=4;i++) for(int j=0;j<=5;j++) { int xx=i; int yy=j; while(ns.map[xx][yy]==0&&ns.map[xx][yy+1]!=0) { int tt=ns.map[xx][yy]; ns.map[xx][yy]=ns.map[xx][yy+1]; ns.map[xx][yy+1]=tt; ret=true; yy--; if(yy<0) break; } } return ret; } bool clear() { bool ret=false; bool cle[5][7]; memset(cle,0,sizeof(cle)); for(int i=0;i<=4;i++)//横向消除 for(int j=0;j<=4;j++) { if(((ns.map[i][j]==ns.map[i][j+1])&&(ns.map[i][j+1]==ns.map[i][j+2]))&&ns.map[i][j]!=0) { cle[i][j]=cle[i][j+1]=cle[i][j+2]=true; ret=true; } } for(int i=0;i<=2;i++)//纵向消除 for(int j=0;j<=6;j++) { if(((ns.map[i+1][j]==ns.map[i+2][j])&&(ns.map[i+1][j]==ns.map[i][j]))&&ns.map[i][j]!=0) { cle[i][j]=cle[i+1][j]=cle[i+2][j]=true; ret=true; } } for(int i=0;i<=4;i++) for(int j=0;j<=6;j++) { if(cle[i][j]) { ns.col[ns.map[i][j]]--; ns.map[i][j]=0; } } return ret; } void solve() { while(1) { bool b1=drop(); bool b2=clear(); if((!b1)&&(!b2)) break; } } void dfs() { for(int i=0;i<=4;i++) for(int j=0;j<=6;j++) for(int k=1;k<=2;k++) { if(!s.empty()) cs=s.top(); else cs=start; ns=cs; now=k==1?k:-1; if(ns.map[i][j]==0) continue; if(i+now>4||i+now<0) continue; if(ns.map[i+now][j]!=0&&now==-1) continue; int t=ns.map[i+now][j]; ns.map[i+now][j]=ns.map[i][j]; ns.map[i][j]=t; ns.step++; ns.stepx[ns.step]=i; ns.stepy[ns.step]=j; ns.cz[ns.step]=now; solve(); if(ns.step>=n) { deal(); continue; } s.push(ns); dfs(); s.pop(); } } int main() { readdata(); start=cs; dfs(); printf("-1\n"); }
相关文章推荐
- 【搜索】【NOIP2011提高组Day1】Mayan游戏
- 「2011NOIP提高组」Mayan 游戏(Mayan Puzzle)
- NOIP提高组2011 Mayan游戏
- 【搜索】【NOIP2011提高组Day1】Mayan游戏
- NOIP2011提高组-Mayan游戏
- [NOIP2011] 提高组 洛谷P1312 Mayan游戏
- 【NOIP2011提高组T3】Mayan游戏-DFS剪枝
- [NOIP2011提高组day1]-3-mayan游戏
- NOIP2011复赛提高组day1(A:铺地毯 B:选择客栈 C:mayan游戏)
- NOIP2011 提高组 Mayan
- NOIP2011 铺地毯 选择客栈 Mayan游戏
- noip2011 mayan游戏 (深搜)
- 【NOIP2011】洛谷1312 Mayan游戏
- 【NOIP2011】Mayan游戏 搜索
- 【noip2011】Mayan游戏
- NOIP 2011 Mayan游戏
- [NOIP 2011] Mayan游戏
- [NOIP 2011] Mayan游戏:搜索,模拟
- NOIP2011 Mayan游戏