Luogu P1312 [Noip2011]Mayan游戏___dfs

版权声明:欢迎借鉴,谢绝抄搬。 https://blog.csdn.net/Gx_Man_VIP/article/details/80667933

题目大意:

给出57的棋盘,棋盘上的每个格子有不同颜色
问在N次操作以后,是否能够使得所有的格子都被消掉。
每次操作可以交换任意两列相邻的格子,格子不能悬空。
例如一个格子的左边为空则左移以后要坠落到一个能够落脚的位置。
当存在任意连续3个格子的颜色相同,则可全部消掉。
当出现行和列都满足消除条件且行列共享某个方块时,行和列上满足消除条件的所有方块会被同时消除。
方块消除之后,消除位置之上的方块将掉落,掉落后可能会引起新的方块消除。
注意:掉落的过程中将不会有方块的消除。
如果有解决方案,请给出N个步骤,每个步骤的描述包括x,y,g(x,y)g为移动的方向
11
注意当多组解时,
按照xy11,给出一组字典序最小的解。
游戏界面左下角的坐标为(0,0)
如果没有解决方案,输出1

这里写图片描述

分析:

数据让我上来就是一发怒搜,
注意优化即可
①每次操作的格子按顺序从左往右选,从下往上选
[x,y][x1,y][x1,y][x,y]
③相同颜色的交换没有意义
12

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>

using namespace std;

int Color[11], Step[6][4], Map[6][8], a[6][8], n, orz = 0, tot = 0;
bool Check = 0;

bool disPlay_Lzy() {
    memset(Color, 0, sizeof(Color));
    for (int i = 1; i <= 5; i++) 
         for (int j = 1; j <= 7; j++) Color[a[i][j]]++;
    for (int i = 1; i <= 10; i++) 
         if (Color[i] >= 1 && Color[i] <= 2) return 0;
    return 1; 
}

void Move_down() {
    for (int i = 1; i <= 5; i++) {
         int k = 0;
         for (int j = 1; j <= 7; j++) {
              if (a[i][j]) a[i][++k] = a[i][j];
              if (k != j) a[i][j] = 0;
         }
    }   
}

int Shut_down() { 
    Move_down();
    ++orz;
    for (int i = 1; i <= 5; i++)
         for (int j = 1; j <= 5; j++)
              if (a[i][j] && a[i][j + 1] && a[i][j + 2])
                  if (a[i][j] == a[i][j + 1] && a[i][j] == a[i][j + 2]) 
                      Map[i][j] = orz, Map[i][j + 1] = orz, Map[i][j + 2] = orz;
    for (int i = 1; i <= 7; i++) 
         for (int j = 1; j <= 3; j++)
              if (a[j][i] && a[j + 1][i] && a[j + 2][i])
                  if (a[j][i] == a[j + 1][i] && a[j][i] == a[j + 2][i])
                      Map[j][i] = orz, Map[j + 1][i] = orz, Map[j + 2][i] = orz;

    int rp = 0;
    for (int i = 1; i <= 5; i++) 
         for (int j = 1; j <= 7; j++)
              if (Map[i][j] == orz) a[i][j] = 0, ++rp;

    if (rp) rp += Shut_down();
    return rp;
}

void Work(int dep, int num) {
    if (!disPlay_Lzy) return;
    if (dep > n) {
        if (!num) {
            for (int i = 1; i <= n; i++) 
                 printf("%d %d %d\n", Step[i][1] - 1, Step[i][2] - 1, Step[i][3]);
            exit(0);
        }
        return;
    }
    Move_down();
    int c[6][8];
    for (int i = 1; i <= 5; i++)
         for (int j = 1; j <= 7; j++) c[i][j] = a[i][j];

    for (int i = 1; i <= 5; i++)
         for (int j = 1; j <= 7; j++) 
              if (c[i][j]) {
                  if (i != 5 && a[i + 1][j] != a[i][j]) {      
                      swap(a[i][j], a[i + 1][j]);
                      Step[dep][1] = i, 
                      Step[dep][2] = j, 
                      Step[dep][3] = 1;

                      int rp = Shut_down();     
                      Work(dep + 1, num - rp);
                      memcpy(a, c, sizeof(c));
                  }

                  if (i != 1 && !a[i - 1][j]) {
                      swap(a[i][j], a[i - 1][j]);
                      Step[dep][1] = i, 
                      Step[dep][2] = j, 
                      Step[dep][3] = -1;

                      int rp = Shut_down();
                      Work(dep + 1, num - rp);
                      memcpy(a, c, sizeof(c));
                  } 
              }              
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= 5; i++) {
         int j = 0, x;
         while (~scanf("%d", &x)) {
                if (!x) break;
                a[i][++j] = x;
                Color[x]++;
                tot++;
         }
    }
    Work(1, tot);
    printf("-1\n");
    return 0;
}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页