这是我的作业,制作数独游戏。我已经完成了算法,但它正在进入无限循环。我不明白为什么。
我正在尝试创建一个随机数并控制它以查找真实数字。检查所有列和行以查找与我们的随机数相同的数字(如果是),它正在更改测试编号,如果测试已更改,则尝试找到另一个数字作为真实编号。简单的数独逻辑。
#include <stdio.h>
#include <stdlib.h>
int main() {
srand(time(NULL));
int num, col, row, row2, col2, test = 0;
int sudo[9][9] = {{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0}};
for (row = 0; row <= 8; row++) {
for (col = 0; col <= 8; col++) {
do {
test = 0;
num = rand() % 9 + 1;
//control
for (col2 = 0; col2 <= 8; col2++) {
if (num == sudo[col2][row]) {
test++;
}
}
for (row2 = 0; row2 <= 8; row2++) {
if (num == sudo[col][row2]) {
test++;
}
}
} while (test > 0);
sudo[col][row] = num;
}
}
//print
for (row = 0; row <= 8; row++) {
for (col = 0; col <= 8; col++) {
printf(" %d ", sudo[col][row]);
if (col == 2 || col == 5) {
printf(" | ");
}
}
if (row == 2 || row == 5) {
printf("\n---------------------------------");
}
printf("\n");
}
}
答案 0 :(得分:2)
你的算法坏了,我可以证明原因。如果有可能以这种方式填充数独谜题,以这种方式解决数独谜题也是微不足道的,但事实并非如此。
基本上,您的代码归结为以下内容。我已经在内部for循环中添加了早期退出,以便在我们找到当前行或列中已有的数字后停止搜索(并且实际上了解了99.9%的世界所关注的&#34;行&# 34;和&#34;列&#34;在NxN矩阵中):
<md-toast style="height:100px;">
随着循环的进行,我们会报告我们正在尝试的号码,以及放置守门员时矩阵的样子。例如,上面的测试运行最初可能如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NSIZE 9
void print_matrix(int const ar[][NSIZE])
{
for (size_t i=0; i<NSIZE; ++i)
{
for (size_t j=0; j<NSIZE; ++j)
{
fputc('0' + ar[i][j], stdout);
fputc(' ', stdout);
}
fputc('\n', stdout);
}
}
int main()
{
srand((unsigned)time(NULL));
int sudo[NSIZE][NSIZE] =
;
int row, col;
for(row=0;row<NSIZE;++row)
{
for(col=0;col<NSIZE;++col)
{
int row2 = 0, col2 = 0, num;
printf("Trying ");
do
{
num = rand()%9+1;
printf("%d ", num);
for(row2=0; row2<NSIZE && num!=sudo[row2][col]; ++row2);
for(col2=0; col2<NSIZE && num!=sudo[row][col2]; ++col2);
}
while (row2 < NSIZE || col2 < NSIZE);
fputc('\n', stdout);
sudo[row][col] = num;
printf("sudo[%d][%d] = %d\n", row, col, num);
print_matrix(sudo);
}
}
}
这可能会持续一段时间。但最终,除非你得到非常幸运,否则必然会发生以下情况(这一轮在车轮脱落之前已经很深了):
Trying 8
sudo[0][0] = 8
8 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 1
sudo[0][1] = 1
8 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 9
sudo[0][2] = 9
8 1 9 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 6
sudo[0][3] = 6
8 1 9 6 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 3
sudo[0][4] = 3
8 1 9 6 3 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 4
sudo[0][5] = 4
8 1 9 6 3 4 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 4 6 7
sudo[0][6] = 7
8 1 9 6 3 4 7 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Trying 1 3 1 3 4 1 3 8 4 9 3 8 1 4 7 9 3 8 8 8 4 9 6 5
sudo[0][7] = 5
8 1 9 6 3 4 7 5 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
请注意,我们即将尝试填充Trying 1 6 3 4
sudo[6][6] = 4
8 1 9 6 3 4 7 5 2
1 3 5 4 8 6 2 7 9
3 6 4 8 7 9 5 2 1
7 9 1 2 4 5 3 8 6
4 7 3 9 2 8 6 1 5
5 4 2 3 6 1 8 9 7
6 8 7 1 9 3 4 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
。为此,我们必须找到一个不在sudo[6][7]
列中的数字,也不是sudo[r][7]
行。但是看看那些位置已有的数字。
sudo[6][c]
因此,我们正在寻找1:9中不在sudo[r][7] : {5,7,2,8,1,9}
sudo[6][c] : {6,8,7,1,9,3,4}
的数字,我们永远不会找到它。
算法被破坏了。回溯用于这样的任务是有原因的。