【发布时间】:2014-01-07 11:28:26
【问题描述】:
我为 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;
}
正如我所说我不知道如何生成所有组合,我只认为我应该调用函数回溯而不是有效的......
【问题讨论】:
-
这是一段很长的不可读的代码,没有任何英文的 cmets,你能详细说明一下“出了什么问题”吗?你有编译错误吗?你得到了什么?
-
是的,我正在检查当前的填充是否有效,如果有效,我会选择下一个值并检查,但我想在递归显示解决方案后继续并进行所有组合。
-
@AlexandruBarbarosie 9*9*9 是 729 (~ 2^10)... 这不是一个很有帮助的评论。 OP试图询问回溯的原理,而不是算法的效率。事实上,如果您自己实际实现并运行了该解决方案,您会看到最坏的情况(一个完全空的网格)在几秒钟内完成,大部分时间都用于 IO。
-
我尝试了您的代码并更新了我的必需品,但是此代码不适用于 9x9,我将 3x3 更改为 9x9 并且它不起作用,我知道它应该多 1/2 if's for row/column check for each number and box check,但我在这里添加了一个调试行:for(k=1;k
-
@asQuirreL 我的计算又错了,我很着急,但你的也不正确。填补一个空的贪婪可能很快不是因为算法好,而是因为它不是最坏的情况,相反,它是最好的!在最坏的情况下,当您感到数独贪婪时,您的算法会尝试在每个框中输入 9 个数字(所有 9 个在他的点上都是有效的),其中 8 个未通过进一步的测试(您无法进一步感觉到某个框)。这意味着每个盒子分支 9 次,这意味着 9^81。