- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我写了一个 3x3 的数独(9 个盒子),我想让它递归并生成所有组合,但我不知道哪里出错了......这是我的代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define dbg 0
using namespace std;
int n,st[100][100];
void afisare()
{
for(int i=1;i<=3;i++) {
for(int j=1;j<=3;j++)
printf("%2d",st[i][j]);
printf("\n");
}
printf("\n");
}
int valid(int k,int ii,int jj)
{
int i,j;
// if(k==1){
// if(dbg)printf("\nReturnez 1 deoarece k-ul este egal cu 1");
// return 1;
// }
for(i=1;i<=3;i++)
for(j=1;j<=3;j++)
if((i==ii) && (j==jj))
{
if(dbg)
printf("\nValorile nu indeplinesc criteriul, se incrementeaza j.");
}
else
{
if(dbg)
printf("\n i= %d j= %d",i,j);
if(dbg)
printf("\nSe verifica daca %d este egal cu casuta %d %d",k,i,j);
if(k==st[i][j]) {
if(dbg)printf("\nValorile sunt egale, returnez 0");
return 0;
}
}
if(dbg)
printf("\nValorile nu sunt egale, deci returnez 1");
return 1;
}
void back(int k)
{
int i,j;
if(dbg) printf("\nk=",k);
for(i=1;i<=3;i++) {
for(j=1;j<=3;j++)
{
if(dbg)
printf("\nVerifica daca casuta %d %d este egal cu 0",i,j);
if(st[i][j]==0) {
if(dbg) printf("\n Este egal cu 0");
if(dbg) printf("\n%d ia valoarea %d.",st[i][j],k);
st[i][j]=k;
if(dbg)
printf("\nSe verifica valabilitatea numarului %d",st[i][j]);
// while(valid(k,i,j)!=0)
if(valid(k,i,j)!=0) {
valid(++k,i,j);
//back(k+1);
}
else
do {
st[i][j]=k+1;
if(dbg)
printf("\nCasuta %d %d are noua valoare %d, veche valoare fiind %d.",i,j,k+1,k);
if(dbg)
("\nValoarea returnata este 0, merg cu urmatoarea valoare %d si verific valabilitatea.",k+1);
//back(k+1);
}
while(valid(++k,i,j)==0);
}
else
if(dbg)
printf("\nNu este egala cu 0 ci are valoarea %d",st[i][j]);
}
}
if(k>9 || st[3][3]!=0)
afisare();
//afisare();
}
int main()
{
int i,j;
freopen("sudoku.in","r",stdin);
for(i=1;i<=3;i++)
for(j=1;j<=3;j++)
scanf("%d",&st[i][j]);
/* for(i=1;i<=3;i++){
for(j=1;j<=3;j++){
printf("%2d",st[i][j]);
}
printf("\n");
}*/
back(1);
system("pause");
return 0;
}
正如我所说,我不知道如何生成所有组合,我只是认为我应该调用函数回溯而不是有效的...
最佳答案
您的代码的问题主要在于格式化和命名。您可能已经通过将递归函数命名为 back
来迷惑自己,原因如下:
要求您找到给定起始条件的所有解决方案的问题的递归解决方案基本上是在解决方案空间中进行深度优先搜索。这意味着每次递归调用都是一个向前移动。
您不会通过调用方法来回溯,而是通过不再调用前向方法来回溯,以允许 DFS 树(递归沿着其中一条路径遍历)向上移动回它正在寻找的路径。
就您而言,您正在使用全局数据结构(st
)来存储您的数独网格。这意味着,当您要回溯时,您需要将网格的状态返回到调用该方法之前的状态。就您而言,这意味着将您 checkin 的位置再次设置为 0。
这是解决方案的指南,以及我解决它的方法,(如果我使用全局数据结构,顺便说一句,这不是很好的编程实践。我建议使用一个类来存储网格)。
首先,一些名称更改:
void afisare()
在我的解决方案中将是 void printGrid()
(实现相同)int valid(int, int, int)
将是 bool isValid(int, int, int)
,并且可以简化。void back(int)
将是 void fillEmpty()
此函数将尝试用所有可能的数字填充下一个空白空间,对于所有有效数字,它将向下递归并再次调用 fillEmpty()
。如果没有剩余的空数字,它将打印网格,因为您已经找到了解决方案。
这就是我所理解的问题的解决方案。
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int grid[3][3];
void
printGrid()
{
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j)
printf("%d ", grid[i][j]);
printf("\n");
}
printf("\n");
}
bool
isValid(int k, int ii, int jj)
{
for(int i = 0; i < 3; ++i)
for(int j = 0; j < 3; ++j) {
if( (i != ii || j != jj) && grid[i][j] == k)
return false;
}
return true;
}
void
fillEmpty()
{
// Find the next empty position.
int i, j; bool foundEmpty = false;
for(i = 0; i < 3; ++i) {
for(j = 0; j < 3; ++j)
if(grid[i][j] == 0) {
foundEmpty = true;
break;
}
if(foundEmpty) break;
}
// If there are no empty positions left
// we have reached a solution, so we
// print it and do nothing else.
if(!foundEmpty)
{
printGrid();
return;
}
// Try every number
for(int k = 1; k <= 9; ++k)
if( isValid(k, i, j) )
{
grid[i][j] = k;
fillEmpty();
}
// Reset the grid position before backtracking.
grid[i][j] = 0;
}
int
main(void)
{
for(int i = 0; i < 3; ++i)
for(int j = 0; j < 3; ++j)
scanf("%d", &grid[i][j]);
printGrid();
fillEmpty();
return 0;
}
关于c - 数独 9 个盒子 ( 3x3 ) C 中的递归回溯所有组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20970458/
在我的类里面,我学习了 Prolog 回溯算法和 Rete forprop 算法,但我也被告知 Rete 可用于进行反向传播。 这是如何运作的?它在哪些方面与 Prolog 回溯相似/不同? 例如,这
两个 friend P1 和 P2 向共同的 friend P3 发送相同的消息 M。 然而由于一些网络损坏,P3 一次只能接收一个字符不知道接收到的字符是属于 P1 还是 P2。 此外,P3 可能会
我最近发了几个理解递归和回溯的问题,我觉得我现在得到了一些东西,并尝试编写一个测试,我确实解决了数独问题,但是当我以另一种格式编写代码时,代码卡了一会儿,返回False,说明这个问题无解。 grid
有人可以指导我或解释如何在 LISP 中执行回溯吗?任何示例或链接将不胜感激。我确实尝试过谷歌,但是他们都没有足够简单的例子让我理解。 谢谢 最佳答案 典型的方法是将不可变状态向下传递到调用堆栈,辅助
我正在使用 apache 2.2.14 运行 Backtrack 5 R2 (ubuntu) 的完全库存安装。我尝试运行一个简单的 index.html 文件,其中包含一些 javascript 代码
如何在 Javascript 中获取回溯? 理想的特征: 入口函数名称,或匿名函数的一些有意义的标识符, 每个级别的参数列表, 行号。 这可以用标准的 ECMAScript 完成吗? 如果没有,是否可
本文首发公众号:小码A梦 回溯算法是一种常见的算法,常见用于解决排列组合、排列问题、搜索问题等算法,在一个搜索空间中寻找所有的可能的解。通过向分支不断尝试获取所有的解,然后找到合适的
Python 是否支持为每个异常/引发/断言显示相同的自定义错误消息(无论代码在哪里中断)? 我目前对它的破解使用了一个装饰器。我有一个函数main它显示回溯很好,但我希望它也打印my_var (在函
输入: 3,4,8,7,3 5,S,7,2,3, 8,5,5,8,10 9,3,3,8,7 6,10,3,G,1 目标是找到从起点(S)到目标(G)的最佳路径。 我们可以向上、向下、向左、向右移动。
我想匹配一个包含“json”(出现超过 2 次)且两个“json”之间没有字符串“from”的字符串。 For example(what I want the string match or not)
我正在尝试使用回溯方法找到熄灯游戏的解决方案。我无法理解此过程的算法。我的方法是枚举从 0 到 2n2 - 1 的所有整数,并将每个整数转换为具有 n*n 位的二进制数。然后,将其分成n2个二进制数字
所以我正在阅读这本书《服从测试山羊》,在学习 Python 时我在第六章中遇到了一个问题。它说我应该能够运行我们在本章和前一章中设置的功能测试,没有错误;但是,我不断收到我不知道如何修复的回溯。 Tr
我需要一些关于 Android 日志文件反混淆的帮助。 问题是如果我有这样的异常: ... 10-16 10:03:10.488: E/AndroidRuntime(25723): Cau
我有一个看起来像这样的表: here | there | -------+-------+ {1,1} | {1,1} | {1,1} | {2,1} | {1,1} | {1,2} |
我写了一小段代码,它应该接受一个字符数组并让它看起来像计算机正在输入文本。很简单,对吧?但是当我运行它时,Terminal 告诉我: *** stack smashing detected ***:
Python 中的堆栈跟踪显示文件路径。有什么方法可以让它们显示完全限定的函数名称吗? 例子: class Foo(object): def bar(self): raise
我决定深入学习回溯的概念,我有以下任务: 给定N个投资者,M个城市,N×M个投资者偏好矩阵P(P[i,j]=1,当第i个投资者希望在第j个城市建矿池;P[i, j] = 0 那么他是中立的,当 P[i
设 E - 图 G 中所有边的集合问题是从G中找到顶点的最小子集S,它满足条件:S = E 中每个顶点的所有出边的总和 换句话说:边是街道,我们可以在顶点上放置路灯。如果我们在一个顶点上放置一盏路灯—
我正在尝试做这个我在查找面试问题时遇到的问题。我们被问及将 r 个硬币放置在 n*m 网格上的方法数量,使得每行和每列至少包含一个硬币。 我想到了一个回溯解决方案,按行主要顺序处理网格中的每个单元格,
我使用 DexGuard混淆。我有来自崩溃日志和映射文件的堆栈跟踪。当我运行 retrace.bat 并为其提供堆栈跟踪和映射文件时,输出仍然是混淆格式。 最佳答案 您是否在使用 ProGuard 的
我是一名优秀的程序员,十分优秀!