记录编号 188403 评测结果 AAAAAAAAAA
题目名称 [NOIP 2011]玛雅游戏 最终得分 100
用户昵称 Gravatarstdafx.h 是否通过 通过
代码语言 C++ 运行时间 0.714 s
提交时间 2015-09-23 08:28:21 内存使用 0.31 MiB
显示代码纯文本
  1. //n=7 m=5
  2.  
  3. #define MAXN 8UL
  4.  
  5. #define REP for(int i=7;i>0;i--) for(int j=1;j<6;j++)
  6.  
  7. #define LEFT -1
  8. #define RIGHT 1
  9.  
  10. #define MAXR 12UL
  11.  
  12. #include <cstdio>
  13. #include <vector>
  14.  
  15. int r,limited_step,Map_Now[MAXN][MAXN],gs_now[MAXN];
  16.  
  17. bool can_arch;
  18.  
  19. struct Point{
  20. int x,y,sp;
  21. inline void Prx(){printf("%d %d %d\n",y-1,7-x,sp);return;}
  22. };
  23.  
  24. std::vector<Point> Move_now;
  25.  
  26. struct Backup{
  27. int Map[MAXN][MAXN],gs[MAXR];
  28. inline void Restore(){REP Map_Now[i][j]=Map[i][j];for(int i=1;i<r;i++) gs_now[i]=gs[i];return;}
  29. inline void Copy(){REP Map[i][j]=Map_Now[i][j];for(int i=1;i<r;i++) gs[i]=gs_now[i];return;}
  30. };
  31.  
  32. inline bool Check_Ok(){for(int i=1;i<=5;i++) if(Map_Now[7][i]) return false;return true;}
  33. inline void Del_Move(){Move_now.pop_back();return;}
  34. inline Point Mk(int x,int y,int k){Point temp;temp.x=x;temp.y=y;temp.sp=k;return temp;}
  35. inline void Add_Move(int x,int y,int mk){Move_now.push_back(Mk(x,y,mk));return;}
  36. inline void Ans_prx(){int s=Move_now.size();for(int i=0;i<s;i++) Move_now[i].Prx();return;}
  37. inline bool Pos_ok(int x,int y){return x>0&&x<8&&y>0&&y<6;}
  38. inline void Push_Down(int x,int y){while(x!=7&&Map_Now[x+1][y]==0) Map_Now[x+1][y]=Map_Now[x][y],Map_Now[x++][y]=0;return;}
  39. inline void Map_Push(int k){for(int i=7;i>0;i--) Push_Down(i,k);return;}
  40. inline bool Sci(){for(int i=1;i<r;i++) if(gs_now[i]>0&&gs_now[i]<3) return true;return false;}
  41. inline bool Killable_X(int x,int y){return Map_Now[x][y+1]==Map_Now[x][y]&&Map_Now[x][y+2]==Map_Now[x][y];}
  42. inline bool Killable_Y(int x,int y){return Map_Now[x+1][y]==Map_Now[x][y]&&Map_Now[x+2][y]==Map_Now[x][y];}
  43. inline void Pm(int p){if(p>r) r=p;return;}
  44.  
  45. inline void Check_Clr(){
  46. while(true){
  47. bool killed=false,Kmap[MAXN][MAXN]={0};
  48. for(int i=7;i>0;i--) for(int j=1;j<4;j++) if(Map_Now[i][j]&&Killable_X(i,j)) killed=true,Kmap[i][j]=Kmap[i][j+1]=Kmap[i][j+2]=true;
  49. for(int i=5;i>0;i--) for(int j=1;j<6;j++) if(Map_Now[i][j]&&Killable_Y(i,j)) killed=true,Kmap[i][j]=Kmap[i+1][j]=Kmap[i+2][j]=true;
  50. for(int j=1;j<=5;j++){
  51. bool Rb=false;
  52. for(int i=7;i>0&&Map_Now[i][j];i--) if(Kmap[i][j]) Rb=true,--gs_now[Map_Now[i][j]],Map_Now[i][j]=0;
  53. if(Rb) Map_Push(j);
  54. }
  55. if(!killed) break;
  56. }return;
  57. }
  58.  
  59. inline bool Move(int x,int y,int op){
  60. if((!Pos_ok(x,y+op))||Map_Now[x][y+op]==Map_Now[x][y]) return false;
  61. if(Map_Now[x][y+op]){Map_Now[x][y]^=Map_Now[x][y+op];Map_Now[x][y+op]^=Map_Now[x][y];Map_Now[x][y]^=Map_Now[x][y+op];}
  62. else Map_Now[x][y+op]=Map_Now[x][y],Map_Now[x][y]=0,Map_Push(y),Map_Push(y+op);
  63. Check_Clr();return true;
  64. }
  65.  
  66. inline void dfs(int step){
  67. if(Sci()) return;
  68. if(Check_Ok()){if(step==limited_step) can_arch=true,Ans_prx();return;}
  69. if(step==limited_step) return;
  70. Backup backup;backup.Copy();
  71. for(int j=1;j<=5;j++){
  72. for(int i=7;i>0&&Map_Now[i][j];i--){
  73. if(Move(i,j,RIGHT)) Add_Move(i,j,RIGHT),dfs(step+1),backup.Restore(),Del_Move();
  74. if(can_arch) return;
  75. if((!Map_Now[i][j-1])&&Move(i,j,LEFT) ) Add_Move(i,j,LEFT ),dfs(step+1),backup.Restore(),Del_Move();
  76. if(can_arch) return;
  77. }
  78. }
  79. return;
  80. }
  81.  
  82. int main(){
  83. freopen("mayan.in","r",stdin);freopen("mayan.out","w",stdout);
  84. scanf("%d",&limited_step);
  85. for(int i=1,s,j=7;i<=5;i++,j=7) while(scanf("%d",&s)&&s) Map_Now[j--][i]=s,Pm(s),++gs_now[s];
  86. r++;dfs(0);if(!can_arch) puts("-1");
  87. return 0;
  88. }