当前位置: 首页 > news >正文

洛谷 P10379 [GESP202403 七级] 俄罗斯方块-普及/提高-

题目描述

小杨同学用不同种类的俄罗斯方块填满了一个大小为 n × m n \times m n×m 的网格图。

网格图由 n × m n \times m n×m 个带颜色方块构成。小杨同学现在将这个网格图交给了你,请你计算出网格图中俄罗斯方块的种类数。
如果两个同色方块是四连通(即上下左右四个相邻的位置)的,则称两个同色方块直接连通;若两个同色方块同时与另一个同色方块直接或间接连通,则称两个同色方块间接连通。一个俄罗斯方块由一个方块和所有与其直接或间接连接的同色方块组成。定义两个俄罗斯方块的种类相同当且仅当通过平移其中一个俄罗斯方块可以和另一个俄罗斯方块重合;如果两个俄罗斯方块颜色不同,仍然视为同一种俄罗斯方块。

例如,在如下情况中,方块 1 1 1 和方块 2 2 2 是同一种俄罗斯方块,而方块 1 1 1 和方块 3 3 3 不是同一种俄罗斯方块。

输入格式

第一行包含两个正整数 n n n m m m,表示网格图的大小。
对于之后的 n n n 行,第 i i i 行包含 m m m 个正整数 a i 1 , a i 2 , … a i m a_{i1}, a_{i2}, \dots a_{im} ai1,ai2,aim,表示该行 m m m 个方块的颜色。

输出格式

输出一行一个整数表示答案。

输入输出样例 #1

输入 #1

5 6
1 2 3 4 4 5
1 2 3 3 4 5
1 2 2 3 4 5
1 6 6 7 7 8
6 6 7 7 8 8

输出 #1

7

说明/提示

子任务分数 n , m ≤ n,m \leq n,m特殊约定
1 1 1 30 30 30 20 20 20所有俄罗斯方块大小不超过 5 × 5 5 \times 5 5×5
2 2 2 30 30 30 500 500 500所有俄罗斯方块大小均为 1 × x 1 \times x 1×x x × 1 x \times 1 x×1 类型,其中 x x x 是任意正整数
3 3 3 40 40 40 500 500 500

对全部的测试数据,保证 1 ≤ n , m ≤ 500 1 \leq n, m \leq 500 1n,m500 1 ≤ a i , j ≤ n × m 1 \leq a_{i,j} \leq n \times m 1ai,jn×m

solution

这道题本质是每一个小整体的中各小方块的相对位置是否相同,如果用固定的搜索顺序的话,每一个方块的搜索方向决定了相对位置。所以可以用搜索方向的方向序列表示唯一表示一种俄罗斯方块。但是需要注意的是,深度优先搜索过程中,某一个位置搜索完成后会回到上一层继续搜索,此时就会出现有可能的不唯一表示,比方说
序列1: 在 A 点处,向下搜索
序列2: 在 A 点处,递归结束,回到 B 点, B 点向下搜索。
可以在每一个点递归结束后添加一个标记即可。

代码

#include <iostream>
#include "bit"
#include "vector"
#include "unordered_set"
#include "set"
#include "queue"
#include "stack"
#include "algorithm"
#include "bitset"
#include "cstring"using namespace std;int col, sx, sy, m, n, mat[501][501];
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
bool vis[501][501];
string s;void dfs(int x, int y) {vis[x][y] = true;for (int i = 0; i < 4; i++) {int xx = x + dx[i];int yy = y + dy[i];if (xx >= 0 && x < m && yy >= 0 && yy < n && !vis[xx][yy] && mat[xx][yy] == col) {s.push_back(char(i + '0'));dfs(xx, yy);}}s.push_back('x');
}int main() {cin >> m >> n;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {cin >> mat[i][j];}}unordered_set<string> set;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (!vis[i][j]) {col = mat[i][j];s.clear();dfs(i, j);set.insert(s);}}}cout << set.size();
}

结果

在这里插入图片描述

相关文章:

  • 使用Vue重新构建应用程序
  • UP COIN:从 Meme 共识走向公链与 RWA 的多元生态引擎
  • 浅析std::atomic<T>::compare_exchange_weak和std::atomic<T>::compare_exchange_strong
  • Docker 与 Containerd 交互机制简单剖析
  • Apache SeaTunnel Spark引擎执行流程源码分析
  • 刀客doc:阿里巴巴集团品牌部划归集团公关管理
  • 数组题解——​轮转数组【LeetCode】
  • [HTML]iframe显示pdf,隐藏左侧分页
  • 线程池 JMM 内存模型
  • 【题解-Acwing】1022. 宠物小精灵之收服
  • docker镜像中集成act工具
  • 非对称加密实战:Python实现数字签名
  • 【AI论文】扩展大型语言模型(LLM)智能体在测试时的计算量
  • Java+Vue开发的SRM招标采购管理系统,实现招标采购全流程数字化、规范化高效管理
  • MySQL与Excel比较
  • 协议转换赋能光伏制造:DeviceNET转PROFINET网关的通信质检实践
  • 2d-gaussian-splatting:论文分析、全流程环境配置与数据集测试【2025最新版!!!】
  • AntDesignPro动态路由配置全攻略
  • AES算法的Verilog流水线实现(带测试)
  • 【机器人-深度估计】双目深度估计原理解析