23. 带旋转的数独游戏

news2024/11/28 6:39:56

题目

Description
数独是一个基于逻辑的组合数字放置拼图,在世界各地都很受欢迎。
在这个问题上,让我们关注  网格的拼图,其中包含  个区域。 目标是用十六进制数字填充整个网格,即 ,以便每列,每行和每个区域包含所有十六进制数字。
下图显示了一个被成功解决的数独例子:


昨天,周老师解决了一个数独并将其留在桌面上。 然而,龙龙想和他开个玩笑——龙龙打算对这个已经解决的数独进行多次以下操作。
 选择一个   的小区域并顺时针旋转  度。
周老师回来发现他拼好的数独板被打乱了,开始挠头,你能帮他以最小的步数恢复原样吗?请你手把手的教他怎么做,也就是需要输出方案。
请注意选择要旋转的方块不能跨越任何小区域,也就是说必须选择一块完整的小区域旋转。小区域的定义在上面, 的网格被分成  个小区域。
Input
第一行输入一个正整数  表示数据组数;
接下来每组数据输入一个  的数独图,表示被龙龙打乱后的数独面板。
Output
对于每组数据:
第一行输出一个整数  ,表示周老师最少需要逆时针旋转多少次才能恢复原样。
接下来输出  行,每行两个数,表示逆时针旋转一次第行第列的小矩阵。


C++完整代码(含详细注释)

有查重!!记得修改呀

#include <iostream>
#include <vector>
#include <cstring>
#include <climits>
using namespace std;

const int N = 16; // 数独面板的大小
int sudoku[N][N]; // 数独面板
int rowCheck[N][N+1]; // 每行数字的出现情况
int colCheck[N][N+1]; // 每列数字的出现情况

struct Node
{
    int x, y, t; // 旋转的位置和次数
};

int minRotations; // 最小旋转次数
vector<Node> curRotation; // 当前旋转方案
vector<Node> minRotation; // 最小旋转方案


// 将小区域逆时针旋转90度
void rotateCounterClockwise(int x, int y) {
    x *= 4; // 将坐标转换成小区域内的坐标
    y *= 4;
    for (int i = 0; i < 2; i++) {
        for (int j = i; j < 3 - i; j++) {
            int temp = sudoku[x + i][y + j];
            sudoku[x + i][y + j] = sudoku[x + j][y + 3 - i];
            sudoku[x + j][y + 3 - i] = sudoku[x + 3 - i][y + 3 - j];
            sudoku[x + 3 - i][y + 3 - j] = sudoku[x + 3 - j][y + i];
            sudoku[x + 3 - j][y + i] = temp;
        }
    }
}


// 检查旋转后的小区域是否合法
bool isValidRotation(int x, int y) {
    x *= 4; // 将坐标转换成小区域内的坐标
    y *= 4;
    for (int i = x; i <= x + 3; i++) {
        for (int j = y; j <= y + 3; j++) {
            int num = sudoku[i][j];
            if (rowCheck[i][num] || colCheck[j][num]) {
                return false;
            }
        }
    }
    // 更新每行和每列数字的出现情况
    for (int i = x; i <= x + 3; i++) {
        for (int j = y; j <= y + 3; j++) {
            int num = sudoku[i][j];
            rowCheck[i][num] = true;
            colCheck[j][num] = true;
        }
    }
    return true;
}

// 撤销旋转操作
void undoRotation(int x, int y) {
     x *= 4; // 将坐标转换成小区域内的坐标
     y *= 4;
    for (int i = x; i < x + 4; i++) {
        for (int j = y; j < y + 4; j++) {
            int num = sudoku[i][j];
            rowCheck[i][num] = false;
            colCheck[j][num] = false;
        }
    }
}

// 深度优先搜索,尝试不同的旋转方案
void dfs(int x, int y, int count) {
    if (x == 4) { // 如果已经遍历完所有小区域
        if (count < minRotations) { // 更新最小旋转次数和旋转方案
            minRotations = count;
            minRotation = curRotation;
        }
        return;
    }

    for (int op = 0; op < 4; op++) { // 尝试不同的旋转次数
        if (!isValidRotation(x, y)) { // 如果旋转后的小区域不合法,继续进行逆时针旋转
            rotateCounterClockwise(x, y);
            continue;
        }

        curRotation.push_back(Node{ x + 1, y + 1, op }); // 将当前旋转方案加入当前旋转方案列表

        if (y == 3) { // 如果已经遍历完当前行的所有小区域,进入下一行
            dfs(x + 1, 0, count + op);
        }
        else dfs(x, y + 1, count + op); // 继续遍历当前行的下一个小区域

        curRotation.pop_back(); // 撤销当前旋转方案
        undoRotation(x, y); // 撤销旋转操作
        rotateCounterClockwise(x, y); // 还原小区域
    }
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        minRotations = INT_MAX;
        curRotation.clear();
        minRotation.clear();
        memset(colCheck, 0, sizeof colCheck);
        memset(rowCheck, 0, sizeof rowCheck);

        // 读入数独面板
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                char hex;
                cin >> hex;
                int dec = stoi(string(1, hex), nullptr, 16);
                sudoku[i][j] = dec;
            }
        }

        dfs(0, 0, 0); // 开始深度优先搜索
        cout << minRotations << endl; // 输出最小旋转次数
        for (auto& per : minRotation) { // 输出最小旋转方案
            for (int i = 0; i < per.t; i++) {
                cout << per.x << " " << per.y << endl;         
            }
        }
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/975762.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ABB机器人20032转数计数器未更新故障报警处理方法

ABB机器人20032转数计数器未更新故障报警处理方法 ABB的机器人上面安装有电池,需要定期进行更换(正常一年换一次),如果长时间不更换,电量过低,就会出现转数计数器未更新的报警,各轴编码器的位置就会丢失,在更换新电池后,需要更新转数计数器。 具体步骤如下: 先用手动…

泛微OA流程表单中代码块获取URL的参数

获取URL的参数 需要编辑自定义函数 function getUrlParam(key){var url decodeURI(window.location.href);var paramMap {};var paramStr url.split("?")[2];if (paramStr && paramStr ! "") {var paramStrArr paramStr.split("&&qu…

客户忠诚度和保留率:不良方法的陷阱

良好的客户忠诚度和保留策略是任何电子商务业务成功的关键因素。但当出现问题时会发生什么&#xff1f;您可以采取哪些措施来鼓励忠诚度并减少客户流失&#xff1f;继续阅读以了解不良客户忠诚度和保留实践的后果。 忠诚度和保留率低下的后果 客户不满意和高流失率 客户忠诚…

直播软件app开发中的AI应用及前景展望

在当今数字化时代&#xff0c;直播市场蓬勃发展&#xff0c;而直播软件App成为人们获取实时信息和娱乐的重要渠道。随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;直播软件App开发正逐渐融入AI的应用&#xff0c;为用户带来更智能、更个性化的直播体验。 …

什么是高压放大器

高压放大器是一种用于放大高电压信号的电子设备。它主要用于需要处理高电压信号的应用&#xff0c;如电力系统、医疗设备、科学研究以及工业和实验室实验等领域。下面将详细介绍高压放大器的原理、特点和应用。 高压放大器的原理基于电子放大技术&#xff0c;通过输入信号放大电…

国腾GM8284DD 将高速串行 LVDS 信号解码为并行 TTL 数据

国腾GM8284DD 1.描述&#xff1a; GM8284C 型 28 位可编程数据选通接收器主要用于视频/图像传输中的接收部分&#xff0c;实现 的功能是将高速串行 LVDS 信号解码为并行 TTL 数据&#xff0c;完成数据的解码功能。该器件可将 4 对串行 LVDS 差分信号在时钟信号作用下…

Java 加了@PreAuthorize注解的接口在Postman中访问

1. 首先&#xff0c;你需要获取一个有效的用户token&#xff0c;该token应包含了相应的接口权限。你可以通过登录或其他身份验证方式来获取token。2. 打开Postman&#xff0c;并确保已选择正确的HTTP方法&#xff08;GET、POST等&#xff09;。3. 在请求的Headers部分&#xff…

【TypeScript学习】—面向对象(四)

【TypeScript学习】—面向对象&#xff08;四&#xff09; 一、面向对象 二、类 三、构造方法 class Dog{name:string;age:number;//构造函数constructor(name:string,age:number){this.namename;this.ageage;}bark(){//在方法中可以通过this来表示当前调用方法的对象//this表…

数据结构零基础入门篇(C语言实现)

前言&#xff1a;数据结构属于C学习中较难的一部分&#xff0c;对应学习者的要求较高&#xff0c;如基础不扎实&#xff0c;建议着重学习C语言中的指针和结构体&#xff0c;万丈高楼平地起。 一&#xff0c;链表 1&#xff09;单链表的大致结构实现 用C语言实现链表一般是使…

Mendix如何实现导出文件

刚刚接触Mendix低代码两周&#xff0c;花了一周在b站看初级视频然后考完初级&#xff0c;第二周开始做个列表查询感觉照葫芦画瓢没啥难度。但最近要求写个导出列表数据&#xff0c;在mendix社区翻了翻&#xff0c;这个功能算是常见的。找了mendix官方提供的Docs磕磕盼盼才实现了…

学会这几步,教你1分钟辨出B站优质UP主!

品牌想要投放某UP主&#xff0c;该如何判断UP主是否优质并且同品牌相匹配呢&#xff1f;运用这一套多维度的UP主评估方法 &#xff0c;帮助你高效判断&#xff0c;快来看看具体怎么操作吧&#xff01; 一、up主粉丝涨跌 有些广告主在判断UP主是否值得投放时&#xff0c;会陷入…

OLED透明屏 裸屏:透明未来的创新之选

OLED透明屏 裸屏作为一项领先的显示技术&#xff0c;正以其独特的优势和创新的设计特点引起广泛关注。 根据市场调研数据显示&#xff0c;预计到2025年&#xff0c;OLED透明屏 裸屏市场规模将达到250亿美元&#xff0c;年均增长率超过25%。 本文将通过深入探讨OLED透明屏 裸屏…

Vue2基础学习

vue基础学习 Vue基础指令v-show 和 v-ifv-on指令v-bind指令v-bind操作classv-bind 操作stylev-for 指令练习&#xff1a;图书管理案例v-model 指令修饰符v-model指令修饰符click.stop-》阻止冒泡按键修饰符阻止默认行为 计算属性计算属性简写computed计算属性VS方法methods计算…

Java版本+企业电子招投标系统源代码+支持二开+Spring cloud

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及…

生成式人工智能促使社会转变

作者&#xff1a;JEFF VESTAL 了解 Elastic 如何处于大型语言模型革命的最前沿 – 通过提供实时信息并将 LLM 集成到数据分析的搜索、可观察性和安全系统中&#xff0c;帮助用户将 LLM 提升到新的高度。 iPhone 社会转变&#xff1a;新时代的黎明 曾几何时&#xff0c;不久前…

别再埋头苦干了,标准化财务数据分析方案开箱即用!

在这个数字化、智能化的时代&#xff0c;一味埋头苦干只会换来效率低下的结果&#xff0c;还是得巧用各种现成资源&#xff0c;以财务数据分析为例&#xff0c;就可以下载奥威BI财务数据分析方案。一键套用&#xff0c;立得覆盖各个主题的财务数据分析报表&#xff0c;快速摸清…

纯前端读写文件?

事情是这样的我发现vscode在线版居然可以打开文件目录和文件&#xff0c;还能保存文件。 兼容性一般 目前 谷歌 edge Opera 支持 其他均不支持 https://vscode.dev/ 查了一下MDN 发现增加新的API 了 https://developer.mozilla.org/zh-CN/docs/Web/API/Window/showDirectoryP…

使用js搭建简易的WebRTC实现视频直播

首先需要一个信令服务器&#xff0c;我们使用nodejs来搭建。两个端&#xff1a;发送端和接收端。我的目录结构如下图&#xff1a;流程 创建一个文件夹 WebRTC-Test。进入文件夹中&#xff0c;新建一个node的文件夹。使用终端并进入node的目录下&#xff0c;使用 npm init 创建p…

易基因:MeRIP-seq等揭示mRNA m6A甲基化调控拟南芥的抗寒性分子机制|植物抗逆

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 植物通过改变数千个基因的mRNA丰度以促进其生理和代谢过程&#xff0c;从而对低温应激进行响应。在转录后水平上&#xff0c;这些冷应激应答转录本经历可变剪接、microRNA介导的调控和可…

气象站的工作内容有哪些?

气象站的工作内容包括观测、记录和报告天气数据。具体来说&#xff0c;气象站需要通过各种传感器和数据记录器来测量和记录气温、湿度、风速、风向、气压、降雨量、雪深等气象参数&#xff0c;对数据的分析、处理和存储。例如&#xff0c;气象站需要将收集到的数据与历史数据进…