蓝桥杯第100 题 九宫幻方 DFS 全排列 C++ 解题思维

题目

九宫幻方icon-default.png?t=N7T8https://www.lanqiao.cn/problems/100/learning/?page=1&first_category_id=1&name=%E4%B9%9D

思路和解题方法  一 (DFS)

  1. 首先,定义了一些全局变量和数组。vis数组用于标记已经出现过的数字,a数组用于存储数独的初始状态和中间状态,ans数组用于存储找到的解决方案,p数组用于存储空白格子的坐标,n表示空白格子的数量,cnt记录解决方案的数量。

  2. check()函数用于检查当前填充的数字是否满足数独的规则。它首先计算对角线上的元素之和,然后检查每行和每列的和是否相等,并返回一个布尔值表示结果。

  3. dfs()函数是核心部分,使用递归实现深度优先搜索。它从第一个空白格子开始填充数字,每次填充一个数字后,递归调用自身继续填充下一个空白格子,直到所有空白格子都填充完毕。如果找到了符合数独规则的解决方案,则将其记录在ans数组中,并增加cnt的计数。

  4. main()函数中,首先读入数独的初始状态,并初始化相关变量。然后调用dfs()函数进行搜索。最后,根据搜索结果输出解决方案或提示"Too Many"表示找到了多个解决方案。

需要注意的是,该程序假设输入的数独有唯一解或没有解。如果存在多个解,则只会输出其中一个解。如果不存在解,则输出"Too Many"表示无法确定唯一解。

c++ 代码  1

#include<bits/stdc++.h>
using namespace std;int vis[10],a[5][5],ans[5][5];
// vis数组用来标记数字是否使用过,a数组记录数独题目的矩阵,ans数组用来存储解决方案
int n=1,cnt;
pair<int ,int>p[10];
// p数组用来存储空白格的坐标,n记录空白格的个数
bool check(){int sum=a[1][1]+a[2][2]+a[3][3];// 先计算左上到右下的斜线上的数字之和if(sum!=a[1][3]+a[2][2]+a[3][1]) return false;// 再计算右上到左下的斜线上的数字之和,如果不相等,则不是数独的解for(int i=1;i<=3;i++){int tmp1=0,tmp2=0;for(int j=1;j<=3;j++)tmp1+=a[i][j],tmp2+=a[j][i];//行和列的和相等 if(tmp1!=sum||tmp2!=sum) return false;}// 分别计算每行每列的数字之和,如果与斜线上的数字之和不相等,则不是数独的解return true;
} void dfs(int now){if(now>=n){if(check()){cnt++;for(int i=1;i<=3;i++)for(int j=1;j<=3;j++)ans[i][j]=a[i][j];// 如果当前数独矩阵是解,则令ans数组等于当前矩阵}return;}int x=p[now].first,y=p[now].second;for(int k=1;k<=9;k++){if(vis[k])continue;a[x][y]=k;vis[k]=1;dfs(now+1);a[x][y]=0;vis[k]=0;// 搜索之前先标记数字已经使用过,搜索完之后再回溯}
}int main()
{for(int i=1;i<=3;i++)for(int j=1;j<=3;j++){cin>>a[i][j];if(!a[i][j])p[n++]=make_pair(i,j);// 记录空白格的坐标vis[a[i][j]]=1;    // 标记数字已经使用过}dfs(1);//从第一个空白格开始搜索if(cnt==1){for(int i=1;i<=3;i++)for(int j=1;j<=3;j++)cout<<ans[i][j]<<" \n"[j==3];}else cout<<"Too Many\n";// 如果有多个解,则输出"Too Many"return 0;}

 思路和解题方法   二 (全排列)

  1. 从标准输入中读入一个包含9个整数的数组a。
  2. 使用next_permutation函数生成arr数组的全排列,并逐个判断是否满足数独的条件。
  3. 如果某个排列满足数独条件,并且与输入数组a匹配,则将该排列赋值给数组a,并增加计数器ans的值。
  4. 最后根据计数器ans的值输出结果。如果有且仅有一个解,则输出解;如果有多个解,则输出"Too Many"。

c++ 代码

#include<iostream>
#include<algorithm>
#include<bits/stdc++.h> //包含一些常用的头文件,例如vector、string等
using namespace std;int a[10]; //定义一个长度为10的数组a,用于存储输入的数独初始状态
int ans = 0; //计数器,用于存储符合数独条件的解的个数
int arr[10] = {1,2,3,4,5,6,7,8,9}; //定义一个长度为10的数组arr,用于生成全排列//检查当前排列是否符合数独条件
bool check(int a[])
{int a1=a[0]+a[1]+a[2];int a2=a[3]+a[4]+a[5];int a3=a[6]+a[7]+a[8];int a4=a[0]+a[3]+a[6];int a5=a[1]+a[4]+a[7];int a6=a[2]+a[5]+a[8];int a7=a[2]+a[4]+a[6];int a8=a[0]+a[4]+a[8];if(a1==a2&&a2==a3&&a3==a4&&a4==a5&&a5==a6&&a6==a7&&a7==a8) //如果8个和相等,则返回true{return true;}return false; //否则返回false
}int main()
{for(int i = 0;i<9;i++) //读入初始数独状态{cin>>a[i];}while(next_permutation(arr,arr+9)){ //生成arr数组的全排列,逐个检查是否符合数独条件if(check(arr)) //如果符合数独条件{bool y = true;for(int i = 0;i<9;i++){if(a[i]!=0&&a[i]!=arr[i]) //如果输入的数独状态不为0且与当前排列不一致,则说明不是想要的解{y = false; //设置标志y为false}}if(y) //如果当前排列与输入的数独状态匹配{for(int i = 0;i<9;i++) //将当前排列赋值给数组a{a[i] = arr[i];}ans++; //计数器ans加1}}}if(ans == 1) //如果只有一个解,则输出该解{int cnt = 0; //计数器cnt,用于输出格式控制for(int i = 0;i<9;i++){if(cnt==3){cout<<endl; //每输出三个数字换行cnt = 0;}cout<<a[i]<<" "; //输出数独解cnt++; //计数器加1}}else { //如果有多个解,则输出"Too Many"printf("Too Many");}return 0;
}

知识点解释

next_permutation() 全排列

next_permutation()是一个函数,通常在编程语言中用于生成给定序列的下一个排列。它可以按照字典序(升序)生成给定序列的下一个排列,并将其更新为下一个排列。

具体而言,next_permutation()函数接受一个序列作为参数,并将该序列重排为下一个字典序更大的排列。如果没有下一个更大的排列,则将序列重排为最小的(升序)排列。该函数返回一个布尔值,指示是否成功生成了下一个排列。

下面是一个示例,展示了如何使用next_permutation()函数来生成给定序列的所有排列:

#include <iostream>#include <algorithm>using namespace std;​int main() {int arr[] = {1, 2, 3};​// 生成并打印所有排列do {for (int i = 0; i < 3; i++) {cout << arr[i] << " ";}cout << endl;} while (next_permutation(arr, arr + 3));​return 0;}

输出结果将是:

 1 2 31 3 22 1 32 3 13 1 23 2 1

这个例子展示了如何使用next_permutation()函数生成给定序列的所有排列,并将它们打印出来。每次调用next_permutation()函数时,原始数组会被修改为下一个排列,直到没有更多的排列可生成为止。

需要注意的是,next_permutation()函数在不同的编程语言和库中可能有略微不同的实现方式,但其基本功能是相似的:生成给定序列的下一个排列。

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ensp 启动设备时报40错误,然后一直没有去管,再次进去就好了,我知道是配置虚拟机的时候修改了一些设置:

第一个阶段&#xff1a; 那时我是重置电脑之后就安装了ensp所以没有出现什么问题&#xff0c;&#xff08;那时没有导入ce6800和12800还有防火墙6000&#xff09; 第二个阶段&#xff1a; 因为有华为相关的实验要做&#xff0c;所以心血来潮打开了ensp&#xff08;路由器之前…

多类场景、遍布各地,融云 IM 支撑多款应用全球增长

&#xff08;全网都在找的《社交泛娱乐出海作战地图》&#xff0c;点击获取&#x1f446;&#xff09; 无论是面向企业场景的工作流协同还是消费场景的网络效应形成&#xff0c;商务社交还是陌生人社交&#xff0c;IM 都是必备组件。IM 遍布互联网各角落&#xff0c;出现在所有…

算法通关村第十二关-黄金挑战字符串冲刺题

最长公共前缀 描述 : 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 题目 : LeetCode 14.最长公共前缀 : 分析 : 第一种方式&#xff0c;我们可以竖着比较&#xff0c;如图所示&#xff0c;每前进一个位置就…

unity学习笔记06

一、预制体 1.定义&#xff1a; 预制体是一种存储了一个或多个游戏对象及其组件的资产。可以将预制体视为游戏对象的模板&#xff0c;它包含了对象的所有属性、组件和初始状态。 2.创建预制体&#xff1a; 在Unity中&#xff0c;可以通过将一个或多个游戏对象拖动到项目窗口…

量子计算软件平台

目录 1.量子语言 2.量子软件开发工具 3.量子云计算平台 1.量子语言 量子语言是一种基于量子计算机的语言&#xff0c;用于描述和实现量子算法。与经典计算机语言不同&#xff0c;量子语言需要考虑量子力学的特殊规则和算法的量子化。其中&#xff0c;最常用的量子语言是量子程…

xxljob学习笔记01(小滴课堂)

分布式调度xxl-job源码部署和数据库建立&#xff1a; 在idea中打开安装包&#xff1a; 创建数据库&#xff1a; 建表&#xff1a; 在项目里&#xff1a; 在navicat里运行语句即可&#xff1a; 修改数据库地址和用户名&#xff0c;密码&#xff1a; 配置令牌&#xff0c;不然谁…

ESP32-Web-Server编程- JS 基础5

ESP32-Web-Server编程- JS 基础5 概述 JS 编程内容颇多&#xff0c;我们提供一些简单的示例&#xff0c;先玩再学&#xff0c;边玩边学。 示例1-演示通过 JS 进行温度转换 资源链接 对应示例的 code 链接 &#xff08;点击直达代码仓库&#xff09; 示例2-增加网页弹窗 演…

SSM跆拳道网站系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 SSM 跆拳道网站系统是一套完善的信息系统&#xff0c;结合springMVC框架完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模…

Mysql的二阶段提交

先看执行器与InnoDB引擎是如何更新一条指定的数据的 可以看到&#xff0c;InnoDB在写redo log时&#xff0c;并不是一次性写完的&#xff0c;而有两个阶段&#xff0c;Prepare与Commit阶段&#xff0c;这就是"两阶段提交"的含义。 为什么要写redo log&#xff0c;不…

springboot+vue实现websocket通信实例,进入页面建立连接

springbootvue实现websocket通信实例 进入页面建立连接 前端代码&#xff1a; <template><div class"app-container"><el-form :model"queryParams" ref"queryForm" size"small" :inline"true" v-show&qu…

将用户的session改为分布式共享session

将用户的session改为分布式session 分布式session理解 使用分布式session的原因&#xff1a; 后台服务器是分布式的&#xff08;比如要负载均衡&#xff09;&#xff0c;在A服务器请求的的信息&#xff08;如用户登录信息&#xff09;存在A的session中&#xff0c;B服务器并不…

记录一次如何查询mysql分库分表数据

一、前言 本次查询是在未知如何分库分表的情况下&#xff0c;对表数据进行查询&#xff0c;其中有的字段为JSON结构。需要提取JSON中某个字段的内容。 二、查询步骤 1、第一方式是将所有分表数据进行union all select * from apporder.ord_shopping_order union all sel…