首页 > 其他分享 >[NOIP2011 提高组] Mayan 游戏

[NOIP2011 提高组] Mayan 游戏

时间:2022-10-01 20:45:58浏览次数:89  
标签:tmp 剪枝 游戏 NOIP2011 int Mayan ++ && nw

Description

link

Solution

令当当前棋盘为 \(a\)。

注意到 \(n\leq 5\) 且棋盘是 \(5\times7\) 的,所以直接爆搜可以做到 \(O(35^5)=O(52521875)\),然而这里还有很大的常数,所以需要剪枝。

剪枝 1:对于第 \(i\) 列,第 \(j\) 行的方块,如果 \(a_{i,j}=0\) 就剪掉,这是显然的。

剪枝 2:对于第 \(i\) 列,第 \(j\) 行的方块,如果 \(j\geq 1\) 并且 \(a_{i,j-1}=a_{i,j}\) 就剪掉。因为两个相同颜色的块互换没有任何意义。

剪枝 3:对于第 \(i\) 列,第 \(j\) 行的方块,如果 \(j\leq 5\) 并且 \(a_{i,j+1}\neq 0\) 就剪掉。因为在 剪枝2 中遍历到 \(i,j+1\) 时并不会被剪掉,所以这种情况会算重。
并且当 \(a_{i,j+1}=0\) 时,遍历到 \(i,j+1\) 时会被 剪枝1 剪掉,所以这个要算上。

Code

代码
#include <bits/stdc++.h>

#ifdef ORZXKR
#include <debug.h>
#else
#define debug(...) 114514
#endif

using namespace std;

typedef vector<int> ln;
typedef unsigned long long ull;

const int dx[] = {1, -1}, dy[] = {0, 0};

int n, cnt;
int a[6][3];
int l[5][7], nw[5][7];

void print() {
  for (int i = 0; i < 5; ++i, fprintf(stderr, "\n")) {
    fprintf(stderr, "%d : ", i);
    for (int j = 0; j < 7 && nw[i][j]; ++j, fprintf(stderr, " ")) {
      fprintf(stderr, "%d", nw[i][j]);
    }
  }
}

bool clr() {
  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 7; ++j) {
      if (nw[i][j]) return 0;
    }
  }
  return 1;
}

void check() {
  for (int i = 1; i <= n; ++i) {
    cout << a[i][0] << ' ' << a[i][1] << ' ' << a[i][2] << endl;
  }
}

bool chk() {
  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 7; ++j) {
      if (!nw[i][j]) continue ;
      if (i - 2 >= 0) {
        if (nw[i][j] == nw[i - 1][j] && nw[i][j] == nw[i - 2][j]) {
          return 0;
        }
      }
      if (i + 2 <= 4) {
        if (nw[i][j] == nw[i + 1][j] && nw[i][j] == nw[i + 2][j]) {
          return 0;
        }
      }
      if (j - 2 >= 0) {
        if (nw[i][j] == nw[i][j - 1] && nw[i][j] == nw[i][j - 2]) {
          return 0;
        }
      }
      if (j + 2 <= 6) {
        if (nw[i][j] == nw[i][j + 1] && nw[i][j] == nw[i][j + 2]) {
          return 0;
        }
      }
    }
  }
  return 1;
}

void drop() {
  int tmp[7];
  for (int i = 0; i < 5; ++i) {
    int c = 0;
    for (int j = 0; j < 7; ++j) {
      if (nw[i][j]) tmp[c++] = nw[i][j];
    }
    for (int j = 0; j < 7; ++j) {
      if (j < c) nw[i][j] = tmp[j];
      else nw[i][j] = 0;
    }
  }
}

void del() {
  int tmp[5][7];
  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 7; ++j) {
      tmp[i][j] = nw[i][j];
    }
  }
  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 7; ++j) {
      if (i - 2 >= 0) {
        if (nw[i][j] == nw[i - 1][j] && nw[i][j] == nw[i - 2][j]) {
          tmp[i][j] = tmp[i - 1][j] = tmp[i - 2][j] = 0;
        }
      }
      if (i + 2 <= 4) {
        if (nw[i][j] == nw[i + 1][j] && nw[i][j] == nw[i + 2][j]) {
          tmp[i][j] = tmp[i + 1][j] = tmp[i + 2][j] = 0;
        }
      }
      if (j - 2 >= 0) {
        if (nw[i][j] == nw[i][j - 1] && nw[i][j] == nw[i][j - 2]) {
          tmp[i][j] = tmp[i][j - 1] = tmp[i][j - 2] = 0;
        }
      }
      if (j + 2 <= 6) {
        if (nw[i][j] == nw[i][j + 1] && nw[i][j] == nw[i][j + 2]) {
          tmp[i][j] = tmp[i][j + 1] = tmp[i][j + 2] = 0;
        }
      }
    }
  }
  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 7; ++j) {
      nw[i][j] = tmp[i][j];
    }
  }
  drop();
  if (chk()) return ;
  del();
}

void dfs(int step) {
  if (step == n + 1) {
    if (!clr()) return ;
    return check(), exit(0);
  }
  if (clr()) return ;
  int tmp[5][7];
  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 7; ++j) {
      if (!nw[i][j]) break ;
      for (int k = 0; k < 2; ++k) {
        int ti = i + dx[k], tj = j + dy[k];
        if (ti < 0 || ti >= 5 || tj < 0 || tj >= 7) continue ;
        if (dx[k] == 1 && nw[ti][tj] == nw[i][j] || dx[k] == -1 && nw[ti][tj]) continue ;
        for (int i = 0; i < 5; ++i) {
          for (int j = 0; j < 7; ++j) {
            tmp[i][j] = nw[i][j];
          }
        }
        a[step][0] = i, a[step][1] = j, a[step][2] = dx[k];   
        swap(nw[i][j], nw[ti][tj]);
        drop(), del();
        dfs(step + 1);
        for (int i = 0; i < 5; ++i) {
          for (int j = 0; j < 7; ++j) {
            nw[i][j] = tmp[i][j];
          }
        }
      }
    }
  }
}

int main() {
  cin >> n;
  for (int i = 0; i < 5; ++i) {
    int x = 1, c = 0;
    while (cin >> x) {
      if (!x || c == 7) break ;
      l[i][c++] = x;
    }
  }
  for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 7; ++j) {
      nw[i][j] = l[i][j];
    }
  }
  dfs(1);
  puts("-1");
  return 0;
}

标签:tmp,剪枝,游戏,NOIP2011,int,Mayan,++,&&,nw
From: https://www.cnblogs.com/Soba/p/16747724.html

相关文章

  • DAPP系统开发及NFT游戏搭建技术
    是元宇宙最重要的一个形态之一啊,随着人们娱乐、生活、工作持续的数字化,包括我们央行的数字人民币。所以游戏呢,可以说是最可以触发原宇宙并抢到红利的一个行业,所以呢,现在很多......
  • #yyds干货盘点# LeetCode 热题 HOT 100:跳跃游戏
    题目:给定一个非负整数数组 nums,你最初位于数组的第一个下标。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标。 示例 1:输入:nums......
  • R语言编程——用不到30行代码,自制成语接龙小游戏
    ​中国文化底蕴深厚,在漫长的历史中,我们的语言文字形成了大量特定的组合,用来表达特定的意思。成语是中国传统文化的一大特色,有的来源于典故,有的则来源于固定的使用方法。在成......
  • 牛客考试7605T2 牛牛的猜球游戏 题解
    2020牛客杯NOIP赛前集训提高第一场T2牛牛的猜球游戏题解目录2020牛客杯NOIP赛前集训提高第一场T2牛牛的猜球游戏题解比赛链接题目题目描述输入格式输出格式样例样例......
  • 谷歌浏览器Chrome小恐龙游戏魔改代码
    打开谷歌浏览器Chrome进入游戏1.断网状态下直接按空格键进入游戏2.有网状态下访问链接chrome://dino按F12,选择控制器Console输入以下代码并按下回车Enter后生效无敌......
  • 学习游戏开发
    学习游戏开发因本身对游戏比较感兴趣,一直想开发一个游戏。所以决定学习游戏开发,如果能挣点生活费就更好了。方案选择首先面临的问题是使用那种游戏引擎。调查目前市面......
  • 从东南亚到中东,为什么社交类产品成为游戏出海的突破口?
    如果说探讨有什么是游戏开发者们永恒关注的话题,且耗费心力深耕的方向,游戏社交应该算得上一个。关注【融云全球互联网通信云】回复白皮书获完整版了解更多从理论而言,游戏中的......
  • 阐述提升游戏虚拟商品销售的5大技巧(转)
    作者:BenSipe在过去一年里我始终致力于帮助免费游戏开发者提高游戏的用户留存和盈利,所以我决定在此列出几点能够促进手机游戏收益发展的5大技巧。1.不要让玩家感到压力根据......
  • 本周四晚19:00知识赋能第八期第3课丨涂鸦小游戏的实现
    本周四晚19:00知识赋能第八期第3课丨涂鸦小游戏的实现​9月29日19:00~20:00,第八期知识赋能最后一节直播就要开始啦!本次直播将在国庆假期前,为同学们带来涂鸦小游戏的趣味体验,让......
  • ios游戏发布流程
    这里假设你已经有苹果的开发者帐号了。其实早在两年前我就已经用过这个了,现在再回忆一下。因为苹果现在为开发者增加了macos的appstore发布权限,也增加了tvOS发布应用权限,......