【回溯】B027_LQ_六角幻方 四阶幻方 九宫幻方 反幻方 魔方状态 纸牌三角形(恶心的剪枝)

本文主要是介绍【回溯】B027_LQ_六角幻方 四阶幻方 九宫幻方 反幻方 魔方状态 纸牌三角形(恶心的剪枝),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、六角幻方

把 1、2、3 … 19 共 19 个整数排列成六角形状,如下:
在这里插入图片描述
要求每个直线上的数字之和必须相等,共有 15 条 直线哦!

再给点线索吧!我们预先填好了 2 个数字,第一行的头两个数字是:15、13,如图。
在这里插入图片描述
请你填写出黄色一行的 5 个数字。数字间用空格分开

方法一:深搜+剪枝

思路

真的恶心,

#include<bits/stdc++.h>
using namespace std;
int a[20]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
int A[19], vis[19];
void dfs(int i) {if (i==7 && 28+A[2] != A[3]+A[4]+A[5]+A[6]) return;if (i==8 && 28+A[2] != A[0]+A[3]+A[7]) return;if (i==12 && (28+A[2] != A[7]+A[8]+A[9]+A[10]+A[11] || 28+A[2] != A[2]+A[6]+A[11])) return;if (i==13 && 28+A[2] != A[1]+A[4]+A[8]+A[12]) return;if (i==16 && (28+A[2] != A[12]+A[13]+A[14]+A[15] || 28+A[2] != A[5]+A[10]+A[15])) return;if (i==17 && (28+A[2] != A[2]+A[5]+A[9]+A[13]+A[16] || 28+A[2]!=A[7]+A[12]+A[16])) return;if (i==18 && (28+A[2] != A[6]+A[10]+A[14]+A[17] || 28+A[2] != A[3]+A[8]+A[13]+A[17])) return;if (i==19 && 28+A[2] == A[16]+A[17]+A[18]) {for (int k=7; k<=11; k++) printf("%d ", A[k]);return;}for (int j=1; j<20; j++) {if (vis[j]) continue;vis[j]=1;A[i]=a[j-1];dfs(i+1);vis[j]=0;}
}
int main() {memset(vis, 0, sizeof vis);A[0]=15, A[1]=13; vis[13]=vis[15]=1;dfs(2);return 0;
}
二、四阶幻方

把1~16的数字填入4x4的方格中,使得行、列以及两个对角线的和都相等,满足这样的特征时称为:四阶幻方。

四阶幻方可能有很多方案。如果固定左上角为1,请计算一共有多少种方案。

比如:
1 2 15 16
12 14 3 5
13 7 10 4
8 11 6 9以及:
1 12 13 8
2 14 7 11
15 3 10 6
16 5 4 9
就可以算为两种不同的方案

代码类似,需要恶心的剪枝…

#include<bits/stdc++.h>
using namespace std;
int ans, A[17], vis[17];void dfs(int i) {if (i==8 && A[0]+A[1]+A[2]+A[3] != A[4]+A[5]+A[6]+A[7]) return;if (i==12 && A[4]+A[5]+A[6]+A[7] != A[8]+A[9]+A[10]+A[11]) return;if (i==13 && (A[8]+A[9]+A[10]+A[11] != A[0]+A[4]+A[8]+A[12] || A[8]+A[9]+A[10]+A[11] != A[3]+A[6]+A[9]+A[12])) return;if (i==14 && A[8]+A[9]+A[10]+A[11] != A[1]+A[5]+A[9]+A[13]) return;if (i==15 && A[8]+A[9]+A[10]+A[11] != A[2]+A[6]+A[10]+A[14]) return;if (i==16) {int s1=A[8]+A[9]+A[10]+A[11], s2=A[12]+A[13]+A[14]+A[15], s3=A[3]+A[7]+A[11]+A[15], s4=A[0]+A[5]+A[10]+A[15];if (s1!=s2 || s1!=s3 || s1!=s4) return;ans++;}for (int next=1; next<17; next++) if (!vis[next]) {vis[next]=1, A[i]=next;dfs(i+1);vis[next]=0;}
}
int main() {std::ios::sync_with_stdio(false);vis[1]=1;A[0]=1;dfs(1);cout << ans;return 0;
}

在这里插入图片描述

三、九宫幻方

小明最近在教邻居家的小朋友小学奥数,而最近正好讲述到了三阶幻方这个部分,三阶幻方指的是将1~9不重复的填入一个3*3的矩阵当中,使得每一行、每一列和每一条对角线的和都是相同的。

三阶幻方又被称作九宫格,在小学奥数里有一句非常有名的口诀:“二四为肩,六八为足,左三右七,戴九履一,五居其中”,通过这样的一句口诀就能够非常完美的构造出一个九宫格来。

4 9 2
3 5 7
8 1 6

有意思的是,所有的三阶幻方,都可以通过这样一个九宫格进行若干镜像和旋转操作之后得到。现在小明准备将一个三阶幻方(不一定是上图中的那个)中的一些数抹掉,交给邻居家的小朋友来进行还原,并且希望她能够判断出究竟是不是只有一个解。

而你呢,也被小明交付了同样的任务,但是不同的是,你需要写一个程序~

输入
输入仅包含单组测试数据。
每组测试数据为一个3*3的矩阵,其中为0的部分表示被小明抹去的部分。
对于100%的数据,满足给出的矩阵至少能还原出一组可行的三阶幻方。
输出
如果仅能还原出一组可行的三阶幻方,则将其输出,否则输出“Too Many”(不包含引号)

样例输入
0 7 2
0 5 0
0 3 0
样例输出
6 7 2
1 5 9
8 3 4
#include<bits/stdc++.h>
using namespace std;int ans, A[10], put[10], bk[10], B[10];
void dfs(int i) {if (i==7 && A[1]+A[2]+A[3]!=A[4]+A[5]+A[6]) return;if (i==8 && (A[4]+A[5]+A[6]!=A[1]+A[4]+A[7] || A[4]+A[5]+A[6]!=A[3]+A[5]+A[7])) return;if (i==9 && A[2]+A[5]+A[8]!=A[4]+A[5]+A[6]) return;if (i==10 && A[7]+A[8]+A[9]==A[2]+A[5]+A[8] && A[7]+A[8]+A[9]==A[1]+A[5]+A[9]) {ans++;for (int j=1; j<10; j++) B[j]=A[j];return;}if (put[i]) {dfs(i+1); } else {for (int j=1; j<10; j++) if (!bk[j]) {bk[j]=1, A[i]=j;dfs(i+1);bk[j]=0;}}
}
int main() {std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);for (int i=1; i<=9; i++) {cin>>A[i];if (A[i]>0) put[i]=true;}dfs(1);if (ans==1) {for (int i=1; i<=9; i++) {cout << B[i] << ' ';if (i%3==0) cout << '\n';}} else {cout << "Too Many";}return 0;
}
四、反幻方

我国古籍很早就记载着

2 9 4 
7 5 3 
6 1 8 

这是一个三阶幻方。每行每列以及对角线上的数字相加都相等。
下面考虑一个相反的问题。
可不可以用 1~9 的数字填入九宫格,使得:每行每列每个对角线上的数字和都互不相等呢?
这应该能做到。
比如:

9 1 2 
8 4 3 
7 5 6 

你的任务是搜索所有的三阶反幻方。并统计出一共有多少种。旋转或镜像算同一种。 比如:

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

3120

{//答案是int row1 = m[0]+m[1]+m[2];int row2 = m[3]+m[4]+m[5];int row3 = m[6]+m[7]+m[8];int col1 = m[0]+m[3]+m[6];int col2 = m[1]+m[4]+m[7];int col3 = m[2]+m[5]+m[8];int xie1 = m[0]+m[4]+m[8];int xie2 = m[2]+m[4]+m[6];int[] p = {row1,row2,row3,col1,col2,col3,xie1,xie2};for(int i=0; i<p.length; ++i)for(int j=i+1; j<p.length; ++j){if(p[i]==p[j])return;}count++;return;
}
五、魔方状态

二阶魔方就是只有2层的魔方,只由8个小块组成。如图所示。

小明很淘气,他只喜欢3种颜色,所有把家里的二阶魔方重新涂了颜色,如下:
前面:橙色、右面:绿色、上面:黄色、左面:绿色、下面:橙色、后面:黄色
请你计算一下,这样的魔方被打乱后,一共有多少种不同的状态。
如果两个状态经过魔方的整体旋转后,各个面的颜色都一致,则认为是同一状态。

六、纸牌三角形

A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
下图就是一种排法这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?

对结果除以 3 再除以 2

这篇关于【回溯】B027_LQ_六角幻方 四阶幻方 九宫幻方 反幻方 魔方状态 纸牌三角形(恶心的剪枝)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/331021

相关文章

算法与数据结构面试宝典——回溯算法详解(C#,C++)

文章目录 1. 回溯算法的定义及应用场景2. 回溯算法的基本思想3. 递推关系式与回溯算法的建立4. 状态转移方法5. 边界条件与结束条件6. 算法的具体实现过程7. 回溯算法在C#,C++中的实际应用案例C#示例C++示例 8. 总结回溯算法的主要特点与应用价值 回溯算法是一种通过尝试各种可能的组合来找到所有解的算法。这种算法通常用于解决组合问题,如排列、组合、棋盘游

HTTP状态码中301与302的区别

一.官方说法  301,302 都是HTTP状态的编码,都代表着某个URL发生了转移,不同之处在于:  301 redirect: 301 代表永久性转移(Permanently Moved)。  302 redirect: 302 代表暂时性转移(Temporarily Moved )。  这是很官方的说法,那么它们的区别到底是什么呢?  1.1、什么是301转向?什么是301重定向?

Zustand 状态管理库简介

1. Zustand 简介 Zustand(德语中意为“状态”)是一个使用简单 API 的 React 状态管理库。它的核心思想是以状态切片(slices)的方式组织应用状态,从而实现高效的状态管理。Zustand 提供了比 Redux 更加简洁和直接的用法,同时支持异步操作和中间件。 在React开发中,状态管理是一个非常重要的概念。虽然 React 提供了 useState 和 useRe

ESP32使用按键配网并通过LED指示网络状态

前言 上面我们已经可以通过 ESPTOUCH 和 Airkiss 给模块配网,并且存储在 nvs 中,重启后仍然可以联网,只是这样仍然不能满足我们实际的应用,这次我们增加按键作为输入,LED作为输出,实现长按按键配网,并可以通过LED指示网络状态。 添加自己的组件 为了让程序结构更加清晰,所以我们在smart_config例程的基础上做了修改,在main文件夹里新建了main.c 、smar

代码随想三刷回溯篇2

代码随想三刷回溯篇2 39. 组合总和题目代码 40. 组合总和 II题目代码 131. 分割回文串题目代码 93. 复原 IP 地址题目代码 78. 子集题目代码 39. 组合总和 题目 链接 代码 class Solution {public List<List<Integer>> combinationSum(int[] candidates

首次使用回声状态网络 (ESN) 和语音特征进行帕金森病 (PD) 预测

帕金森病(Parkinson's disease, PD)是一种使人衰弱的神经退行性疾病,它需要进行精确和早期的诊断,以便为患者提供有效的治疗和护理。这种疾病是由James Parkinson在1817年首次确定的,其特征是多巴胺生成神经元的退化。多巴胺的不足导致了一系列症状,包括静止性震颤、肌肉僵硬、运动迟缓(姿势不稳定)、以及其他重要特征,如睡眠障碍、心律失常、便秘和语音变化,这

java编程:命令行输入的三个整数判断是否构成三角形,不能就抛异常。

写一个方法void sanjiao(int a,int b,int c),判断三个参数是否能构成一个三角形,如果不能则抛出 异常IllegalArgumentException,显示异常信息“a,b,c不能构成三角形”, 如果可以构成则显示三角形三个边长,在主方法中得到命令行输入的三个整数,调用此方法,并捕获异常。 附源代码: package 异常;public class Sa

Kubernetes排错(七)-Pod 状态一直 ContainerCreating

查看 Pod 事件 $ kubectl describe pod apigateway-6dc48bf8b6-l8xrw -n cn-staging 异常原因 1)no space left on device ...Events:Type Reason Age From Me

194.回溯算法:组合总和||(力扣)

代码解决 class Solution {public:vector<int> res; // 当前组合的临时存储vector<vector<int>> result; // 存储所有符合条件的组合// 回溯函数void backtracing(vector<int>& candidates, int target, int flag, int index, vector<bool>&

React学习(二)——状态(数据)与状态修改

useState 在React中,useState 是一个非常重要的Hook,它允许你在函数组件中添加“状态”(state)。在传统的React类组件中,我们使用this.state来管理和更新组件的状态。然而,在函数组件中,由于它们没有实例,因此我们不能直接使用this.state。这时,useState Hook 就派上了用场。  在函数组件中,你可以使用useState来声明