zoukankan      html  css  js  c++  java
  • P1312 [NOIP2011 提高组] Mayan 游戏

    题面

    一起来打块。。。。dnm,调了一晚上==

    知识点:模拟,搜索

    操作:掉块,消块,移块,判最终是否合法。

    掉块:注意有空块的时候才掉,对于每一列从下往上扫一遍就好。

    消块:有连续三块才能消,但不是一遇到三块能消,这样如果有连续的五块,剩两块就没法消了,所以对能消的块先打个标记,最后一起消了就好了。注意:如果能消,肯定要执行一次掉块操作,执行完掉块还要进行消块,因为掉块可能会导致重新组合成可以新的可以消的块,直到不能消了位置,用一个循环实现就好。

    移块:(dfs)​​ 枚举每一步移动哪一个块,记录移动之前的状态方便回溯,过程中把答案记下就好了。

    移块时剪枝:一个块向左移,要保证左边没有快,如果向右移要保证右边有不同颜色的块。

    判最终是否合法:看最下面一行是否为空就好了。

    code

    /*
    work by:Ariel_
    */
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    #define ll long long
    #define rg register
    using namespace std;
    int read(){
        int x = 0,f = 1; char c = getchar();
        while(c < '0'||c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') {x = x*10 + c - '0'; c = getchar();}
        return x*f;
    }
    struct Ans{
       int x, y, d;
    }ans[6];
    int n, k, mp[6][8], fag, last[6][6][8], Step;//mp[i][j]: x = i, y = j; 起始从(1, 1)开始,按照数学坐标系模拟
    bool res[6][8];
    void down() {//掉落 
       for (int i = 1; i <= 5; i++) {
         int x = 0;
       	 for (int j = 1; j <= 7; j++) {
       	      if (!mp[i][j]) x++;
    		  else {
    		  	if (x == 0) continue; 
    		  	mp[i][j - x] = mp[i][j], mp[i][j] = 0;
    		  }
    	   }
       }
    }
    bool delet() {//消除操作 
       int flag = 0; 
       for (int i = 1; i <= 5; i++) {
       	  for (int j = 1; j <= 7; j++) {
       	  	   if (i - 1 >= 1 && i + 1 <= 5 && mp[i - 1][j] == mp[i][j] && mp[i + 1][j] == mp[i][j] && mp[i][j]) {
       	  	   	    res[i - 1][j] = 1, res[i][j] = 1, res[i + 1][j] = 1, flag = 1;
    			}
    		   if(j - 1 >= 1 && j + 1 <= 7 && mp[i][j - 1] == mp[i][j] && mp[i][j] == mp[i][j + 1] && mp[i][j]) {
    		   	    res[i][j] = 1, res[i][j - 1] = 1, res[i][j + 1] = 1, flag = 1;
    		   }
    		}
       }
       if (flag == 0) return false; 
       for (int i = 1; i <= 5; i++) {
       	  for (int j = 1; j <= 7; j++) {
       	  	   if (res[i][j]) mp[i][j] = 0, res[i][j] = 0;
    		}
       }
       return true; 
    }
    void move(int x, int y, int d) {
       swap(mp[x][y], mp[x + d][y]);
       down();
       while(delet()) down();//连续消 
    } 
    bool check() {
       for (int i = 1; i <= 5; i++) if (mp[i][1]) return 0;
       return 1;
    } 
    void copy(int x) {
       for (int i = 1; i <= 5; i++) {
       	  for (int j = 1; j <= 7; j++) {
       	  	   last[x][i][j] = mp[i][j];   
    		}
       }
    }
    void dfs(int step) {
      if (check()) {
      	 for (int i = 1; i <= n; i++) {
      	    printf("%d %d %d
    ", ans[i].x, ans[i].y, ans[i].d);	 
    	 }
    	 exit(0);
      }
      if (step == n + 1) return ;//超步数
      copy(step);
      for (int i = 1; i <= 5; i++) {
      	 for (int j = 1; j <= 7; j++) {
      	   if (mp[i][j]) {
      	   	   if (i + 1 <= 5 && mp[i][j] != mp[i + 1][j]){//右侧没有方块 
      	   	       move(i, j, 1);
    			   ans[step].x = i - 1, ans[step].y = j - 1, ans[step].d = 1;
                   dfs(step + 1);
    			   for (int i = 1; i <= 5; i++) {
    			   	 for (int j = 1; j <= 7; j++) {
    			   	 	    mp[i][j] = last[step][i][j];
    					}
    			   }
    			   ans[step].x = -1, ans[step].y = -1, ans[step].d = -1;	
    			}
    		   if (i - 1 >= 1 && mp[i - 1][j] == 0) {
    		   	   move(i, j, -1);
    		   	   ans[step].x = i - 1, ans[step].y = j - 1, ans[step].d = -1;
    		   	   dfs(step + 1);
    		   	   for (int i = 1; i <= 5; i++) {
    		   	   	  for (int j = 1; j <= 7; j++) {
    		   	   	  	   mp[i][j] = last[step][i][j];
    				    }
    				}
    			   ans[step].x = -1, ans[step].y = -1, ans[step].d = -1;
    		   }
    		}
    	 }
      }
    }
    int main(){
       n = read();
       memset(ans, -1, sizeof ans);
       for (int i = 1, tot, x; i <= 5; i++) {
       	  x = read(), tot = 1;
       	  while(x) {mp[i][tot++] = x, x = read();}
       }
    
       dfs(1);
       puts("-1");
       return 0;
    }
    
  • 相关阅读:
    【MySql学习笔记】MySql索引
    【MySql学习笔记】MySql事务
    【计算机网络学习笔记】TCP三次握手与四次挥手
    【设计模式学习笔记】单例模式
    【设计模式学习笔记】设计模式概述
    【设计模式学习笔记】七大原则『二』
    改变input tpye 属性radio css 样式!!!
    js常用汇总
    js判断是否移动端及浏览器内核
    100多个基础常用JS函数和语法集合大全
  • 原文地址:https://www.cnblogs.com/Arielzz/p/15101251.html
Copyright © 2011-2022 走看看