NOIP2011玛雅游戏
闲的没事干,出来写一下早两天刷的一道搜索题NOIP2011玛雅游戏,其实这道题还是比较水的,虽然看起来可能有点复杂。
方法很简单粗暴,直接根据规则模拟就行。
话不多说直接上代码(关键操作在注释中有提到):
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) #define ll long long #define il inline #define RG register #define inf (1<<30) using namespace std; il int gi(){ RG int x=0,q=1; RG char ch=getchar(); while( ( ch<'0' || ch>'9' ) && ch!='-' ) ch=getchar(); if( ch=='-' ) q=-1,ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; } int n,a,b; int map[ 6 ][ 8 ],step[ 10 ][ 3 ]; bool broken[ 6 ][ 8 ],appear[ 11 ]; int color,sum[ 11 ]; il bool check(){ memset( sum,0,sizeof( sum ) ); for( RG int i=1;i<=5;i++ ) for( RG int j=1;j<=7;j++ ) sum[ map[ i ][ j ] ]++; for( RG int i=1;i<=color;i++ ) if( sum[i] && sum[i]<=2 ) return false; //若块数小于3则无法消去 return true; } il int count(){ memset( broken,0,sizeof( broken ) ); RG int left,right,top,bottom; RG int ans=0,drop=0; for( RG int i=1;i<=5;i++ ) for( RG int j=1;j<=7;j++ ) if( map[ i ][ j ] ) if( j==1 || ( j>1 && map[ i ][ j-1 ] ) ){//找到一个没有悬空的块 left=right=i; top=bottom=j; while(left>1 && map[left-1][j]==map[i][j]) left--; while(right<4 && map[right+1][j]==map[i][j]) right++; while(top<7 && map[ i ][top+1]==map[i][j]) top++; while(bottom>1 && map[i][bottom-1]==map[i][j]) bottom--; //统计可以消除的块 if( right-left+1>=3 ) for( RG int k=left;k<=right;k++ ) broken[ k ][ j ]=1; if( top-bottom+1>=3 ) for( RG int k=top;k>=bottom;k-- ) broken[ i ][ k ]=1; } for( RG int i=1;i<=5;i++ ) for( RG int j=1;j<=7;j++ ) if( broken[ i ][ j ] ) ans++,map[ i ][ j ]=0; RG int i,j,down,up; for( i=1;i<=5;i++ ){ j=1; while( j<=7&&map[ i ][ j ] ) j++; down=j; //找到该列第一个空块 while( j<=7&&!map[ i ][ j ] )j++; up=j-1;////找到该列最后一个空块 if( up==7 ) continue;//若道顶端都没有悬空的块就跳过该列 RG int k=0; for( j=down;j<=7;j++ ){//下落操作 k++; if( map[i][j] || !map[i][up+k] ) break; map[i][j]=map[i][up+k]; map[i][up+k]=0; drop=1; } } //**下落的块还会造成其他块消除,所以再次统计** if( drop ) ans+=count(); return ans; } il void dfs( int ste,int cnt ){//分别表示已走步数和剩余块数 if( !check() )return ; if( ste>n ){ if( !cnt ){ for( RG int i=1;i<=n;i++ ) printf("%d %d %d \n",step[i][0]-1,step[i][1]-1,step[i][2]); exit(0); } return ; } int mapp[ 6 ][ 8 ],if_change,x; for( RG int i=1;i<=5;i++ ) for( RG int j=1;j<=7;j++ ) mapp[i][j]=map[i][j]; for( RG int i=1;i<=5;i++ ) for( RG int j=1;j<=7;j++ ){ if( map[i][j] ){//找到可以移动的块 if_change=1; if( i<5 && map[i][j]!=map[i+1][j] ){ //考虑到结果的优先原则,先进行右移操作 swap( map[i][j],map[i+1][j] ); step[ste][0]=i; step[ste][1]=j; step[ste][2]=1; x=cnt-count(); dfs( ste+1,x ); if_change=0; } if( !if_change ){//回溯 for( RG int g=1;g<=5;g++ ) for( RG int s=1;s<=7;s++ ) map[g][s]=mapp[g][s]; if_change=1; } if( i>1 && !map[i-1][j] ){ //只有左边没有块的时候才交换,否则就会和前面往右 //移的步骤重复 swap( map[i][j],map[i-1][j] ); step[ste][0]=i; step[ste][1]=j; step[ste][2]=-1; x=cnt-count(); dfs( ste+1,x ); if_change=0; } if( !if_change ) for( RG int g=1;g<=5;g++ ) for( RG int s=1;s<=7;s++ ) map[ g ][ s ]=mapp[ g ][ s ]; } } } il void init(){ n=gi(); for( RG int i=1;i<=5;i++ ){ RG int j=0; a=gi(); while( a ){ map[ i ][ ++j ]=a; if( !appear[ a ] ) appear[ a ]=1,color++; a=gi(); b++; } } } int main(){init();dfs( 1,b );printf( "-1\n" );return 0;}
NOIP2011玛雅游戏的更多相关文章
- [NOIP2011]玛雅游戏
闲的没事干,出来写一下早两天刷的一道搜索题NOIP2011玛雅游戏,其实这道题还是比较水的,虽然看起来可能有点复杂. 方法很简单粗暴,直接根据规则模拟就行. 话不多说直接上代码(关键操作在注释中有提到 ...
- noip2011 玛雅游戏 大模拟
深搜+模拟 需要剪枝:同一移动向右移了就不需要向左移了 #include<cstdio> #include<cstring> #include<iostream> ...
- [COGS 622] [NOIP2011] 玛雅游戏 模拟
整个模拟的关键除了打出来就是一个剪枝:对于两个左右相邻的块你不用再走←,因为走→是等效的 #include<cstdio> #include<cstring> #include ...
- Luogu 1312 【NOIP2011】玛雅游戏 (搜索)
Luogu 1312 [NOIP2011]玛雅游戏 (搜索) Description Mayan puzzle 是最近流行起来的一个游戏.游戏界面是一个7行5列的棋盘,上面堆放着一些方块,方块不能悬空 ...
- 玛雅游戏[NOIP2011]
题目描述 Mayan puzzle 是最近流行起来的一个游戏.游戏界面是一个7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...
- [NOIP2011] mayan游戏(搜索+剪枝)
题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...
- [NOIP2011]Mayan游戏 题解
题目大意: 有一个5*7的方格,上面有几种颜色的方块,如果在一横行或者竖列上有连续三个或者三个以上相同颜色的方块,则它们将立即被消除,方块消除之后,消除位置之上的方块将掉落.每步移动可以且仅可以沿横向 ...
- NOIP2011 Mayan游戏
3 Mayan游戏 题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上 ...
- Noip2011 Mayan游戏 搜索 + 模拟 + 剪枝
写了一下午,终于AC了. 由于n<=5, 所以不需要太多的剪枝和技巧也能过.可以将操作后的消方块和下落和剪枝函数写到一个结构体中,这样会减少调试难度,更加简洁. 可以采用如下剪枝: 1. 如果当 ...
随机推荐
- java基础之IO篇
IO流 在计算机中的流是有方向的即为IO流,分为输入流和输出流,他们的方向都是以服务的方向为主,向服务器中发送指令等等就是输出流,服务器给出的反应等等,我们都说为输出流. 字节流 字符流 输入流 In ...
- XML配置文件中写版本号.xsd和不写版本号的区别
如果写版本号则默认从网上下载并指定最新版本,如果不写版本号则默认从本地下载并使用最新版本.
- 解决Yii2邮件发送问题(结果返回成功,但接收不到邮件)
刚刚用了一下yii邮件发送功能,虽然结果返回成功,但接收不到邮件.配置文件代码如下: 'components' => [ 'db' => [ 'class' => 'yii\db\C ...
- 摘记:Web应用系统测试内容
表示层: 内容测试,包括整体审美.字体.色彩.拼写.内容准确性和默认值 Web站点结构,包括无效的链接或图形 用户环境,包括Web浏览器版本和操作系统配置(每一个浏览器都有不同的脚本引擎或虚拟机在客户 ...
- 解决kubuntu(KDE4.8.5桌面环境)找不到中文语言包
原始日期:2013-12-30 23:16 接触linux的想必都知道KDE平台,kde精美的界面是其一大特色,不过美中不足的是,很多新手在安装完KDE后,界面包括菜单选项等都是英文界面,对于英语水平 ...
- 如何退出 Vim
点击 Esc 键,; Vim 进入命令模式.然后输入: :q 退出(这是 :quit 的缩写) :q! 不保存退出(这是 :quit! 的缩写) :wq 写入文件并退出:(这是 :writequi ...
- 百度统计API的使用
百度统计API的使用 在搭建自己博客的时候,希望自己能有个日志系统,能够看到PV.UV等信息,同时自己也搭建了个ELK系统,可惜服务器配置太低(1GHZ+1G内存),根本运行不起来.只能使用第三方的日 ...
- Chrome控制台使用详解
Chrome的开发者工具已经强大到没朋友的地步了,特别是其功能丰富界面友好的console,使用得当可以有如下功效: 更高「逼格」更快「开发调试」更强「进阶级的Frontender」 Bug无处遁形「 ...
- tcp/ip通信传输流
利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信,发送端从应用层往下走,接收端则往应用层方向走. 我们用HTTP进行举例 客户端在应用层发出想要看到某个web页面的http请求.HT ...
- 把编译安装的httpd 实现服务脚本,通过service和chkconfig 进行管理
把编译安装的httpd 实现服务脚本,通过service和chkconfig 进行管理 1 编译安装httpd 把httpd编译安装在/app/httpd/目录下. 2 在/etc/rc.d/init ...