用c ++修改八皇后谜题程序

时间:2015-11-27 05:01:00

标签: c++

所以八个皇后拼图已经解决了很多次,但我还没有在c ++中看到一个程序,它允许用户输入一行来开始搜索。

分配方向:修改此程序以便 main()不必仅从行0开始。而是程序将读取开始行 键盘上的数字(在0到7的范围内)。对中的四个函数进行适当的修改 原始程序,它仍然可以打印出从指定行开始的可行放置。

这是原始程序的代码:

#include <iostream>
using namespace std;
const int NUMBER_OF_QUEENS = 8; // Constant: eight queens
int queens[NUMBER_OF_QUEENS];
// Check whether a queen can be placed at row i and column j
bool isValid(int row, int column)
{
 for (int i = 1; i <= row; i++)
 if (queens[row - i] == column // Check column
 || queens[row - i] == column - i // Check upper left diagonal
 || queens[row - i] == column + i) // Check upper right diagonal
 return false; // There is a conflict
 return true; // No conflict
}
// Display the chessboard with eight queens
void printResult()
{
 cout << "\n---------------------------------\n";
 for (int row = 0; row < NUMBER_OF_QUEENS; row++)
 {
 for (int column = 0; column < NUMBER_OF_QUEENS; column++)
 printf(column == queens[row] ? "| Q " : "| ");
 cout << "|\n---------------------------------\n";
 }
}
// Search to place a queen at the specified row
bool search(int row)
{
 if (row == NUMBER_OF_QUEENS) // Stopping condition
 return true; // A solution found to place 8 queens in 8 rows
 for (int column = 0; column < NUMBER_OF_QUEENS; column++)
 {
 queens[row] = column; // Place a queen at (row, column)
 if (isValid(row, column) && search(row + 1))
 return true; // Found, thus return true to exit for loop
 }
 // No solution for a queen placed at any column of this row
 return false;
}
int main()
{
 search(0); // Start search from row 0. Note row indices are 0 to 7
 printResult(); // Display result
 return 0;
}

这是我到目前为止编写的代码,它没有正确运行,我只是略微修改了。我不完全确定如何解决这个问题,但main()与修改它应该完全一样。

#include <iostream>
using namespace std;
const int NUMBER_OF_QUEENS = 8; // Constant: eight queens
int queens[NUMBER_OF_QUEENS];
// Check whether a queen can be placed at row i and column j
bool isValid(int row, int column)
{
    for (int i = 1; i <= row; i++)
        if (queens[row - i] == column // Check column
            || queens[row - i] == column - i // Check upper left diagonal
            || queens[row - i] == column + i) // Check upper right diagonal
            return false; // There is a conflict
    return true; // No conflict
}
// Display the chessboard with eight queens
void printResult(int row)
{
    cout << "\n---------------------------------\n";
    for (row; row < NUMBER_OF_QUEENS; row++)
    {
        for (int column = 0; column < NUMBER_OF_QUEENS; column++)
            printf(column == queens[row] ? "| Q " : "| ");
        cout << "|\n---------------------------------\n";
    }
}
// Search to place a queen at the specified row
bool search(int row)
{
    if (row == NUMBER_OF_QUEENS) // Stopping condition
        return true; // A solution found to place 8 queens in 8 rows
    for (int column = 0; column < NUMBER_OF_QUEENS; column++)
    {
        queens[row] = column; // Place a queen at (row, column)
        if (isValid(row, column) && search(row + 1))
            return true; // Found, thus return true to exit for loop
        }
        // No solution for a queen placed at any column of this row
        return false;
    }
    int main()
    {
        int inputRow;
        cout << "Enter the row to search from:" << endl;
        cin >> inputRow;
        search(inputRow); // Start search from row 0. Note row indices are 0         to 7
    printResult(inputRow); // Display result
    return 0;
}

现在我对编程和网站都很陌生,因为我去年开始使用Java而且仅仅一个半月前就开始使用c ++,所以如果我格式化错误或者说这个措辞不是很好,我很抱歉,但我对这个问题感到非常难过,并且非常感谢程序员在这个网站上花费的任何时间以及你可以给我的任何帮助。

2 个答案:

答案 0 :(得分:1)

您的实施中存在一些错误。

如果要概括算法,可以让用户选择第一个女王的位置(行和列)。

#include <iostream>
using namespace std;
const int NUMBER_OF_QUEENS = 8; // Constant: eight queens
int queens[NUMBER_OF_QUEENS];

bool isValid(int row, int column);
bool search(int q);
                                    // Display the chessboard with the queens
void printResult()
{
    cout << "\n+---+---+---+---+---+---+---+---+\n";
    for ( int row = 0; row < NUMBER_OF_QUEENS; row++)
    {
        for (int column = 0; column < NUMBER_OF_QUEENS; column++)
            printf(column == queens[row] ? "| Q " : "|   ");
        cout << "|\n+---+---+---+---+---+---+---+---+\n";
    }
}

int main() {
    int iRow, iColumn;

    cout << "Please, enter the row and the column of the cell where you want to put the first Queen into." << endl;
    cout << "Input values must be in the range 0 - " << NUMBER_OF_QUEENS << ". Enter a letter to stop." << endl;        
    while (cin >> iRow && cin >> iColumn) {
        if ( iRow < 0 || iRow > NUMBER_OF_QUEENS - 1
             || iColumn < 0 || iColumn > NUMBER_OF_QUEENS - 1 ) continue;

        for ( int k = 0; k < NUMBER_OF_QUEENS; k++) queens[k] = - NUMBER_OF_QUEENS;
        queens[iRow] = iColumn;             // initialize the array with significant values. Ugly, I know.

        if ( !search(0) )                   // Start the search
            cerr << "Error: Unable to find a solution!\n";      
        printResult();                  // Display result
        }
    return 0;
}

您的检查功能没有完成扫描,我更喜欢这个:

// Check whether a queen can be placed at row i and column j
bool isValid(int row, int column)
{
    int d1 = column - row;
    int d2 = column + row;
    for (int i = 0; i < NUMBER_OF_QUEENS; i++) {
        if ( queens[i] == column                // Check column
            || queens [i] == d1                 // Check diagonals
            || queens [i] == d2 )
                return false; // There is a conflict
       d1++;
       d2--;
    }
   return true; // No conflict
}

但主要问题是搜索功能,它必须尝试一个可能的位置,如果它无效则拒绝它:

// Search to place a queen at the specified row
bool search(int q)
{
    if (q >= NUMBER_OF_QUEENS)                          // Stopping condition, all rows visited
        return true;                                    // A solution found to place 8 queens in 8 rows
    if ( queens[q] != -NUMBER_OF_QUEENS )               // Skip the row if a queen is already there
        return search(q+1);                 
    else {

        for (int column = 0; column < NUMBER_OF_QUEENS; column++) {
            if (isValid(q, column)) {                   // First check, then
                queens[q] = column;                     // place a queen at (row, column)
                if ( search(q + 1) )  return true;      // Found, thus return true to exit for loop
                else queens[q] = - NUMBER_OF_QUEENS;    // Reject the wrong position
            }
        }
    }
        // No solution for a queen placed at any column of this row
    return false;
}

现在您可以测试该程序。例如,如果输入2 5,则输出为:

+---+---+---+---+---+---+---+---+
|   | Q |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+
|   |   |   | Q |   |   |   |   |
+---+---+---+---+---+---+---+---+
|   |   |   |   |   | Q |   |   |
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   | Q |
+---+---+---+---+---+---+---+---+
|   |   | Q |   |   |   |   |   |
+---+---+---+---+---+---+---+---+
| Q |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   | Q |   |
+---+---+---+---+---+---+---+---+
|   |   |   |   | Q |   |   |   |
+---+---+---+---+---+---+---+---+

答案 1 :(得分:0)

您所做的更改肯定存在错误

在printResult中,您添加了一个'row'参数;但是,它实际上并没有被使用,因为for语句声明了另一个变量'row',它掩盖了它。

如果您想了解更多详细信息,您将不得不详细描述您遇到的问题(编译器错误,运行时错误,输出错误等)。

另请注意,isValid(int row, int column)会查看queens[row - i]的内容以做出决定。您的方法将跳过初始行,因此isValid将无法获得做出正确决策所需的信息。我建议必须完成搜索所有行,只需打印一行,你需要。