我已经用C++代码编写了一个函数来解决八个皇后问题.该程序应打印出所有92种可能的解决方案.我只能跑到40岁.不知道问题出在哪里.尝试调试,但我仍然卡住了.
#include "stdafx.h"
#include <cmath>
#include <iostream>
using namespace std;
bool ok(int board[8][8]){
for(int c = 7; c > 0; c--){
int r = 0;
while(board[r][c] != 1 ){
r++;
} // while loop
for(int i = 1; i <= c; i++){
if(board[r][c-i] == 1)
return false;
else if (board[r-i][c-i] == 1)
return false;
else if (board[r+i][c-i] == 1)
return false;
} // for loop
} // for loop
return true;
} // ok
void print(int board[8][8], int count){
cout << count << endl;
for(int i = 0; i < 8; i++){
for(int j = 0; j < 8; j++){
cout << board[i][j];
} // for loop
cout << endl;
} // for loop
cout << endl;
} // print board
int main (){
int board[8][8]={0};
int count = 0;
for(int i0 = 0; i0 < 8; i0++)
for(int i1=0; i1 < 8; i1++)
for(int i2 = 0; i2 < 8; i2++)
for(int i3 = 0; i3 < 8; i3++)
for(int i4 = 0; i4 < 8; i4++)
for(int i5 = 0; i5 < 8; i5++)
for(int i6 = 0; i6 < 8; i6++)
for(int i7 = 0; i7 < 8; i7++){
board[i0][0]=1;
board[i1][1]=1;
board[i2][2]=1;
board[i3][3]=1;
board[i4][4]=1;
board[i5][5]=1;
board[i6][6]=1;
board[i7][7]=1;
if(ok(board))print(board, ++count);
board[i0][0]=0;
board[i1][1]=0;
board[i2][2]=0;
board[i3][3]=0;
board[i4][4]=0;
board[i5][5]=0;
board[i6][6]=0;
board[i7][7]=0;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Tyl*_*nry 14
你的问题在于ok功能.它有三个错误,都与矩阵的界限有关.第一个错误(如果有任何原因导致您收到太多解决方案),请在此处:
for(int c = 7; c > 0; c--){
Run Code Online (Sandbox Code Playgroud)
这将永远不会检查第0列.测试应该是c >= 0.
另外两个导致不可预测行为的错误在这里:
for(int i = 1; i <= c; i++){
if(board[r][c-i] == 1)
return false;
else if (board[r-i][c-i] == 1)
return false;
else if (board[r+i][c-i] == 1)
return false;
} // for loop
Run Code Online (Sandbox Code Playgroud)
这可能导致ok函数返回任意数量的漏报.就我而言,使用这两个错误编译和运行程序不会产生任何解决方案.它只是偶然为您生产40种解决方案.
问题再次出现问题.的i变量是从1向上移动并包括c,使c-i移动从向下c-1到0,如预期.
但是,您没有检查它r-i并r+i保持在矩阵的范围内.考虑的情况是r = 7和i = 4.然后,r+i = 11它超过行的末尾.类似地,如果r = 0且i不是0,则为r-i负数并且超过行的开头.
您需要添加其他检查以确保此循环中的测试中使用的行值在0到7的范围内.您可以利用C++中逻辑运算符的短路行为来执行此操作,例如:
else if (<test> && board[r-i][c-i] == 1)
Run Code Online (Sandbox Code Playgroud)
只会检查board[r-i][c-i]是否<test>属实.
我要离开将这两个错误的修正添加为练习,因为这很可能是一个家庭作业(如果是,你应该在问题中添加[homework]标签).