1 条题解
-
0
题目分析
本题要求模拟一个复杂的消消乐游戏,包含多种特殊效果和计分规则。需要准确处理交换、消除、下落、连锁反应和多种计分方式。
算法思路
核心思想:模拟 + 搜索
主要流程:
- 检查操作有效性
- 处理消除和连锁反应
- 计算各类奖分
- 更新棋盘状态
算法流程详解
1. 操作有效性检查
bool chk(int x, int y, int xx, int yy) { // 检查相邻、非空、交换后能形成三连 swap(mp[x][y], mp[xx][yy]); if (!tri()) { swap(mp[x][y], mp[xx][yy]); return 0; } return 1; }2. 主颜色记录
void gmaincol(int x, int y, int xx, int yy) { // 记录通过直接交换被消除的颜色 if (clr[x][y]) lst[cnt].emplace_back(mp[x][y].a); if (clr[xx][yy]) lst[cnt].emplace_back(mp[xx][yy].a); }3. 消除检测与处理
基础三连检测
bool ctri() { // 检测行和列的三连 for (int i = 1; i < n - 1; i++) for (int j = 1; j <= m; j++) if (mp[i][j].a && mp[i][j].a == mp[i+1][j].a && ...) clr[i][j] = clr[i+1][j] = clr[i+2][j] = 1; // 类似处理列 }特殊效果传播
bool gspch() { // 处理特殊效果的连锁触发 for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { if (clr[i][j] && mp[i][j].b && !upded[i][j]) { upded[i][j] = 1; colsp(i, j, mp[i][j].b); // 触发特殊效果 } } }4. 计分系统
消除奖分
void Sakuzyo() { int sum = 0; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) if (clr[i][j]) sum += mp[i][j].a; scr += sum * rnd; // 第r轮消除 }组合奖分
void scupd() { // DFS计算连通块大小 for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { if (clr[i][j] && !vis[i][j]) { trcnt = 0; dfs(i, j, mp[i][j].a); scr += 50 * (trcnt - 3) * (trcnt - 3); } } }牌型奖分
// 枚举最近5次操作的主颜色组合 for (auto v1 : lst[cnt-4]) for (auto v2 : lst[cnt-3]) ... { map<int, int> mp; // 统计颜色出现次数 // 根据牌型规则计算奖分 if (mp.size() == 5) nscr += 50 + max_color; // 高牌 else if (mp.size() == 4) nscr += 100 + pair_color; // 一对 // ... 其他牌型 }5. 重力下落
void falldown() { for (int i = n; i >= 1; i--) for (int j = 1; j <= m; j++) { if (mp[i][j].a) { int pos = i; while (pos < n && !mp[pos+1][j].a) ++pos; swap(mp[i][j], mp[pos][j]); } } }
关键技术与优化
1. 连锁反应处理
- 使用
upded数组标记已触发的特殊效果,避免重复触发 - 在单轮消除内完成所有特殊效果传播
2. 状态标记
clr[][]:标记待消除的棋子vis[][]:DFS访问标记upded[][]:特殊效果触发标记
3. 主颜色追踪
- 只记录通过直接交换被消除的颜色
- 保存最近5次操作的主颜色用于牌型计算
4. 牌型枚举优化
- 直接枚举所有可能的颜色组合
- 由于数据范围小(最多2种主颜色×5次操作),暴力可行
复杂度分析
- 单次操作:最坏 (多次连锁消除)
- 牌型计算:
- 总体:,对于 可接受
样例验证
样例1
- 5次有效操作
- 计算消除奖分、连锁奖分、组合奖分
- 第5次操作后计算牌型奖分:两对(1,2,4,2,4) → 210分
- 终局奖分:1000 + 10000 = 11000
- 总分:315+417+429+435+482 + 210 + 11000 = 11692
样例2
- 包含无效操作,失去终局奖分
- 总分较低
算法优势
- 逻辑完整:严格按题意实现所有规则
- 模块清晰:分离消除检测、特殊效果、计分等模块
- 边界处理:妥善处理各种边界情况
- 可扩展性:易于添加新的特殊效果或计分规则
该算法通过系统的状态管理和模块化设计,完整实现了复杂的消消乐游戏逻辑。
- 1
信息
- ID
- 4698
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者