闲的没事干,出来写一下早两天刷的一道搜索题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]玛雅游戏的更多相关文章

  1. NOIP2011玛雅游戏

    闲的没事干,出来写一下早两天刷的一道搜索题NOIP2011玛雅游戏,其实这道题还是比较水的,虽然看起来可能有点复杂. 方法很简单粗暴,直接根据规则模拟就行. 话不多说直接上代码(关键操作在注释中有提到 ...

  2. noip2011 玛雅游戏 大模拟

    深搜+模拟 需要剪枝:同一移动向右移了就不需要向左移了 #include<cstdio> #include<cstring> #include<iostream> ...

  3. [COGS 622] [NOIP2011] 玛雅游戏 模拟

    整个模拟的关键除了打出来就是一个剪枝:对于两个左右相邻的块你不用再走←,因为走→是等效的 #include<cstdio> #include<cstring> #include ...

  4. Luogu 1312 【NOIP2011】玛雅游戏 (搜索)

    Luogu 1312 [NOIP2011]玛雅游戏 (搜索) Description Mayan puzzle 是最近流行起来的一个游戏.游戏界面是一个7行5列的棋盘,上面堆放着一些方块,方块不能悬空 ...

  5. 玛雅游戏[NOIP2011]

    题目描述 Mayan puzzle 是最近流行起来的一个游戏.游戏界面是一个7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...

  6. [NOIP2011] mayan游戏(搜索+剪枝)

    题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...

  7. [NOIP2011]Mayan游戏 题解

    题目大意: 有一个5*7的方格,上面有几种颜色的方块,如果在一横行或者竖列上有连续三个或者三个以上相同颜色的方块,则它们将立即被消除,方块消除之后,消除位置之上的方块将掉落.每步移动可以且仅可以沿横向 ...

  8. NOIP2011 Mayan游戏

    3 Mayan游戏 题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上 ...

  9. Noip2011 Mayan游戏 搜索 + 模拟 + 剪枝

    写了一下午,终于AC了. 由于n<=5, 所以不需要太多的剪枝和技巧也能过.可以将操作后的消方块和下落和剪枝函数写到一个结构体中,这样会减少调试难度,更加简洁. 可以采用如下剪枝: 1. 如果当 ...

随机推荐

  1. SQL Server Management Studio 键盘快捷键

    光标移动键盘快捷键 操作 SQL Server 2012 SQL Server 2008 R2 左移光标 向左键 向左键 右移光标 向右键 向右键 上移光标 向上键 向上键 下移光标 向下键 向下键 ...

  2. python迭代器的内置函数

    1.迭代器: 内置函数: (1)iter() -__iter__() (2)next() -__next__() 2.迭代器的举例; 对于Fibs数列,我们对其进行 限量输出: 实现代码如下: cla ...

  3. 来源自rnnoise,但非rnn

    很快又一年过去了. 自学音频算法也近一年了. 不记得有多少个日日夜夜, 半夜醒来,就为验证算法思路. 一次又一次地改进和突破. 傻逼样的坚持,必然得到牛逼样的结果. 这一年,主要扎音频算法上. 经常有 ...

  4. 2.深入解析数据类型与变量——《Excel VBA 程序开发自学宝典》

    2.1 数据类型 数据类型 所占字节 Byte 1 Boolean 2 Integer 2 Long 4 Single 4 Double 8 Currency 8 Decimal 14 Date 8 ...

  5. PLSQL触发器,游标

    --触发器 drop table emp_log create table emp_log( empno number, log_date date, new_salary number, actio ...

  6. Deep learning for visual understanding: A review 视觉理解中的深度学习:回顾 之一

    Deep learning for visual understanding: A review 视觉理解中的深度学习:回顾 ABSTRACT: Deep learning algorithms ar ...

  7. Python-RabbitMQ(持久化)

    生产者: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import pika   connection = pika.BlockingConnection(pi ...

  8. oraclejdbc

    https://segmentfault.com/q/1010000004952621/a-1020000004955600

  9. DB2分页查询简单示例

    select * from ( select a.* ,rownumber() over(order by create_time desc) as rowid from ( select * fro ...

  10. M1阶段的开发过程的一些反思

    今天八组队伍都做了项目的展示,和他们相比,我们的团队项目是显得最单薄的了,这里面的原因很多,固然我们团队整体的实力 比较弱,但是我们在M1项目开发过程中的种种错误表现也是导致我们项目失利的重要原因.下 ...