惠特曼 大路之歌 英文:改一个八皇后程序

来源:百度文库 编辑:高校问答 时间:2024/04/27 21:24:04
#include <iostream.h>
int array2[8];
int num=0; //计算八皇后解的个数
void findqueen(int queennum,int deep,int x,int y)
{
int i;
if(deep==queennum) //完成一种解法并输出
{
if(array2[x]==y)
{
char A[8][8]; //字符数组记录排列
int l;
for(i=0;i<8;i++) //Q为皇后的位置,*为无皇后的位置
for(l=0;l<8;l++)
A[i][l]='*'; //初始化,全部置*
for(i=0;i<8;i++)
A[i][array2[i]]='Q'; //皇后位置改为Q
for(i=0;i<queennum;i++) //输出皇后位置坐标
cout<<"<"<<i+1<<","<<array2[i]+1<<"> ";
cout<<endl;
for(i=0;i<8;i++) //输出字符数组,即皇后排列
{
for(l=0;l<8;l++)
cout<<A[i][l]<<" ";
cout<<endl;
}
num++; //累计解的个数
}
}
else //一种排列未完成
{
int j,check;
for(j=0;j<queennum;j++) //查找某行,直到找到皇后位置为止
{
check=1; //假设皇后的位置正确
for(i=0;i<deep;i++)
{
if(array2[i]==j||array2[i]-j==i-deep||array2[i]-j==deep-i) //在同一列,同一正斜线、反斜线上时,
check=0; //该位置不能放皇后,check=0
}
if(check==1) //若该位置正确
{
array2[deep]=j;
deep++; //深度+1,即放下一个棋子
findqueen(queennum,deep,x,y); //递归查找下一个皇后位置
deep--; //深度-1,为下一种解法做准备
}
}
}
}
void main()
{
for(int i=1;i<=8;i++) //相加并显示第一行皇后的排列,8行总数为92
{
findqueen(8,0,0,i-1); //查找皇后的位置
}
cout<<"共有"<<num<<"解"<<endl;
}

能不能帮我改得非常规范,思路清晰,算法问题希望更改得尽量简洁合理.这个还是原来程序改动过的,改动前的程序,老师说动态创建多个数组的算法很不合理,不知道这个改动后的有没彻底解决问题.

<<C & C++ 编程百例>>上的例子

// QUEEN.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream.h>

enum BOOLEAN
{
FALSE = 0,
TRUE = 1
};
enum STATUS
{
EMPTY = 0,
HAVE = 1
};

const int max_length = 20;

class QUEEN
{
public:
QUEEN(int length = 8); // 设置棋盘的宽度
void reset(); // 设置初始状态

// 给出八皇后问题的第一个解
// 如果有解返回TRUE,否则返回FALSE
BOOLEAN get_first_solution();

// 给出八皇后问题的下一个解
// 在第一次调用之前必需先调用get_first_solution()
// 如果有下一个解返回TRUE,否则返回FALSE
BOOLEAN get_next_solution();

// 用直观的方式显示八皇后问题的一个解
// 必需先调用get_first_solution()或get_next_solution
void display_solution();
private:
// 选择当前行(current_row)放皇后的列位置,选择的结果在(current_col)
// 如果有可以放皇后的位置饭后TRUE,否则返回FALSE
BOOLEAN select_place();

void forward(); // 从当前行(current_row)推进到下一行

void backward(); // 从当前行(current_row)推进到下一行

// 判断是否回溯到初始状态
// 如果回到初始状态返回TRUE,否则返回FALSE
BOOLEAN back_to_start();

// 判断是否推进到最后一步
// 如果推进到最后一步返回TRUE,否则返回FALSE
BOOLEAN is_end();

// 判断在第row行、第col列是否能够放皇后
// 如果能够放皇后返回TRUE,否则返回FALSE
BOOLEAN check(int row, int col);

STATUS board[max_length][max_length]; // 模拟棋盘及皇后放置的情况

int solution[max_length]; // 记住每行放皇后的列位置

// 当前正在试探的行和列
int current_row;
int current_col;

int length; // 记住每行放皇后的列位置
};

QUEEN::QUEEN(int length)
{
if (length > max_length) length = max_length;
QUEEN::length = length;
reset();
}

void QUEEN::reset()
{
int i, j;
for (i = 0; i < length; i++)
for (j = 0; j < length; j++) board[i][j] = EMPTY;
for (i = 0; i < length; i++) solution[i] = length;
current_row = 0;
current_col = 0;
}

void QUEEN::display_solution()
{
int row, col;
for (col = 0; col < length; col++)
cout << "+---"; cout << "+\n";
for (row = 0; row < length; row++)
{
for (col = 0; col < length; col++)
{
if (col == solution[row])
cout << "| Q ";
else
cout << "| ";
}
cout << "|\n";
for (col = 0; col < length; col++)
cout << "+---"; cout << "+\n";
}
}

BOOLEAN QUEEN::get_first_solution()
{
reset();
return get_next_solution();
}

BOOLEAN QUEEN::get_next_solution()
{
// 从上一解回溯,实际上这里的条件current_row >= length为永真
if (current_row >= length)
current_row = length - 1;

// 使用回溯算法求问题的一个解
do {
if (select_place()) forward();
else backward();
} while (!back_to_start() && !is_end());

if (back_to_start())
return FALSE;
else
return TRUE;
}

BOOLEAN QUEEN::select_place()
{
if (solution[current_row] >= length)
current_col = 0; //当前行没有试探过,从第0列开始
else
current_col = solution[current_row] + 1; //从上一次试探的下一列重新开始

// 选择在当前行可放皇后的列
while (!check(current_row, current_col) && current_col < length)
{
current_col = current_col + 1;
}
if (current_col >= length)
return FALSE; //当前行没有可放皇后的列位置
else
return TRUE;
}

void QUEEN::forward()
{
if (solution[current_row] < length)
{
// 当前行在上一次试探时放过皇后,要清除上一次放皇后的标记
board[current_row][solution[current_row]] = EMPTY;
}
solution[current_row] = current_col; //记住当前行放皇后的列
board[current_row][current_col] = HAVE; //标记该位置放置了皇后
current_row = current_row + 1; //推进到下一行
}

void QUEEN::backward()
{
if (solution[current_row] < length)
{
// 当前行曾经放过皇后,清除放皇后的标记
board[current_row][solution[current_row]] = EMPTY;

// 标记该行没有试探过,或者说要从第0列再重新试探
solution[current_row] = length;
}
current_row = current_row - 1; //回溯到上一行
}

BOOLEAN QUEEN::back_to_start()
{
if (current_row < 0) return TRUE;
else return FALSE;
}

BOOLEAN QUEEN::is_end()
{
if (current_row >= length) return TRUE;
else return FALSE;
}

BOOLEAN QUEEN::check(int row, int col)
{
int temp_row, temp_col;

// 判断同一列是否已经放置皇后
for (temp_row = row; temp_row >= 0; temp_row = temp_row - 1)
if (board[temp_row][col] == HAVE) return FALSE;

// 判断左上斜线是否已经放置皇后
for (temp_row = row, temp_col = col;
temp_row >= 0 && temp_col >= 0;
temp_row = temp_row - 1, temp_col = temp_col - 1)
{
if (board[temp_row][temp_col] == HAVE) return FALSE;
}

// 判断右上斜线是否已经放置皇后
for (temp_row = row, temp_col = col;
temp_row >= 0 && temp_col < length;
temp_row = temp_row - 1, temp_col = temp_col + 1)
{
if (board[temp_row][temp_col] == HAVE) return FALSE;
}

return TRUE;
}

int main()
{
QUEEN queen(8);
int count = 0; // 记录解的数目

if (queen.get_first_solution()) //求第一解
{
queen.display_solution();
count++;
}
else
cout << "Can not find any solution!\n";

while (queen.get_next_solution()) //通过不断地求下一个解来得到所有解
{
queen.display_solution();
count++;
}

cout << "Find " << count << " solutions!\n";
return 0;
}