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

(C++回溯算法)微信小程序“开局托儿所”游戏

问题描述

给定一个矩阵 A = ( a i j ) m × n \bm A=(a_{ij})_{m\times n} A=(aij)m×n,其中 a i j ∈ { 1 , 2 , ⋯ , 9 } a_{ij}\in\{1,2,\cdots,9\} aij{1,2,,9},且满足 ∑ i = 1 m ∑ j = 1 n a i j \sum\limits_{i=1}^m\sum\limits_{j=1}^na_{ij} i=1mj=1naij被10整除。玩家每次操作需要选择 A \bm A A中某个所有非空元素之和为10的子矩阵,并将其中所有的元素都标记为空。求按何种顺序消除能将 A \bm A A中所有的元素都标记为空,若存在则返回该解决方案,否则返回空列表。

代码

nursery_game.h

#ifndef NURSERY_GAME
#define NURSERY_GAME
#include <vector>
#include <stdint.h>
struct Operate {uint8_t x1, y1, x2, y2;Operate() {}Operate(uint8_t i1, uint8_t j1, uint8_t i2, uint8_t j2):x1(i1), y1(j1), x2(i2), y2(j2) {}
};
std::vector<Operate> solve(int8_t *data, uint8_t m, uint8_t n);
#endif

nursery_game.cpp

#include "nursery_game.h"
#include <utility>
using std::vector;// #define RECOVER_DATA // 若希望不改变A的值请解开本行注释#define handle(x1,y1,x2_start,tag) for(uint8_t x2=x2_start;x2<m;){uint8_t ie=x2*n;for(uint8_t y2=y1;y2<n;y2++){uint8_t sum=0;for(uint8_t i=is;i<=ie;i+=n)for(uint8_t j=i+y1,e=i+y2;j<=e;j++){int8_t t=A[j];if(t>0&&(sum+=t)>10)goto tag;}if(sum!=10)continue;vector<uint8_t> set;for(uint8_t i=is;i<=ie;i+=n)for(uint8_t j=i+y1,e=i+y2;j<=e;j++){int8_t t=A[j];if(t>0){A[j]=-t;set.push_back(j);}}R.emplace_back(x1,y1,x2,y2);unRemoveCount-=set.size();posSet.push_back(std::move(set));goto F_push;}tag:x2++;}// A: 矩阵A数据,逐行排列
// m: 矩阵A行数
// n: 矩阵A列数
vector<Operate> solve(int8_t *A, uint8_t m, uint8_t n) {vector<Operate> R;vector<vector<uint8_t>> posSet;Operate op;uint8_t unRemoveCount = m * n, is;
F_push:if (!unRemoveCount) {
#ifdef RECOVER_DATAint8_t *p = A + m * n;do {--p;*p = -*p;} while (p != A);
#endifreturn std::move(R);}is = 0;for (uint8_t x1 = 0; x1 < m; x1++, is += n)for (uint8_t y1 = 0; y1 < n; y1++)handle(x1, y1, x1, F1)
F_pop:if (R.empty()) return {};op = R.back();R.pop_back();unRemoveCount += posSet.back().size();for (auto pos : posSet.back()) A[pos] = -A[pos];posSet.pop_back();is = op.x1 * n;handle(op.x1, op.y1, op.x2 + 1, F2)for (uint8_t y1 = op.y1 + 1; y1 < n; y1++) handle(op.x1, y1, op.x1, F3)for (uint8_t x1 = op.x1 + 1; x1 < m; x1++) {is += n;for (uint8_t y1 = 0; y1 < n; y1++) handle(x1, y1, x1, F4)}goto F_pop;
}

test.cpp

#include "nursery_game.h"
#include <stdio.h>
using namespace std;int main() {int8_t data[] = { 4,7,3,3,6,5,4,4,2,1,8,4,2,2,2,6,1,2,3,2,3,2,7,1,2,8,1,3,1,6,4,5,4,5,1,4,2,2,2,3,8,3,3,1,9,2,3,3,1,1,4,4,1,9,3,7,1,3,2,5,3,1,1,5 };vector<Operate> r(solve(data, 8, 8));for (auto op : r) printf("(%d,%d) (%d,%d)\n", op.x1, op.y1, op.x2, op.y2);return 0;
}

测试结果

(0,1) (0,2)
(0,0) (2,1)
(0,0) (3,1)
(0,7) (1,7)
(1,3) (1,6)
(0,4) (3,4)
(1,3) (5,3)
(0,3) (2,5)
(0,3) (4,5)
(0,4) (6,4)
(2,0) (2,6)
(0,2) (4,2)
(0,2) (4,6)
(5,0) (7,0)
(5,7) (6,7)
(6,0) (7,2)
(5,0) (6,3)
(0,1) (5,6)
(0,5) (7,5)
(4,0) (6,7)
(3,7) (7,7)
(0,0) (7,7)

操作过程:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21


http://www.mrgr.cn/news/66765.html

相关文章:

  • 数据结构 C/C++(实验一:线性表)
  • C++网络编程之IO多路复用(一)
  • WPF 特性------Binding
  • Thrift
  • 若依框架-添加测试类-最新
  • 数据结构(8.7_3)置换——选择排序
  • mysql 安装 windows
  • 第三百一十二节 Java线程教程 - Java多线程
  • AI 写作(一):开启创作新纪元(1/10)
  • Sourcetree 配置第三方比较工具
  • AI Prompt如何帮你提升论文中的逻辑推理部分?
  • 深⼊理解指针(1)
  • 02- 模块化编程-006 ADC0808数码显示对比
  • 【VScode】调试
  • 号码品牌认证:有效提升企业外呼接通率
  • 腾讯轻量云服务器docker拉取不到镜像的问题:拉取超时
  • 【大模型实战项目】基于Langchain与ChatGLM等语言模型的本地知识库问答项目(附教程)
  • go语言环境配置
  • 计算机毕业找什么工作,计算机就业指南(非常详细)零基础入门到精通,收藏这篇就够了
  • 鲲鹏生态繁荣的“幕后推手”:虹信软件扛起“智改数转”大旗
  • 基于Spring Boot的药品管理系统的设计与实现,LW+源码+讲解
  • ssm+jsp653基于Javaweb的网上花店系统的设计与实现
  • 【AIStarter】共创未来:AI赛道一起创业!
  • Mysql海量数据经常有下面这些操作,离被开除就不远了(持续更新)
  • Mysql执行一模一样的语句,一个报错,一个成功
  • rclone挂载后如何优化性能?