算法实验四:八皇后问题

实验三:贪心算法:旅行商问题(TSP)
问题描述:有若干个城市,任意两个城市之间交通费是确定的,现在一旅行商从某城市出发经过每一个城市且仅经过一次,最后回到原来的城市,确定一条路线使得旅行费最少。
实验四:八皇后问题。
问题描述:由N2个方块排成N行N列的正方形,称为N元棋盘,在N元棋盘上放置N个皇后,如果某两个皇后位于N元棋盘的同一行或同一列或同一斜线(斜率为±1)上,则称它们在互相攻击,试设计算法找出使N个皇后互不攻击的所有布局。
解题思路;

  • 首先:写一个判断第k个皇后的位置是否符合规定的函数。
    因为循环递增变量i可以限定不在同一行,这样的话用X[i]来限定不在同一列,即:x≠X[i]
    在同一主对角线上:行-列的值都相等 i-X[i]=k-X[k]
    在同一反对角线上:行+列的值都相等 i+X[i]=k+X[k]
    可以推出来主对角线和反对角线通用公式:|X[i]-X[k]|=|i-k|,若不在一条对角线上,则需保证ABS(|X[i]-X[k]|)≠ABS(i-k)
    从i=1到k若都使得该皇后不在同一行或列或对角线上,则成立,否则不成立。

  • 接下去按算法书上的伪代码模拟了一遍主函数的执行了。

  • 主函数思路如下:
    step1:定义行变量k和列变量X[k],k赋初值1,X[k]赋初值0
    step2:定义while(k>0)循环,因为k初值为1,所以当回溯回来k=0的时候,就结束程序了。
    step3:将X[k]自增1,定义判断该皇后的位置是否符合标准的while(X[k]<=n同时不合标准)循环,这时列自增1。
    step4:若找到位置且X[k]<=n,则先判断是否n个皇后都有位置了(k=n),若都有位置,则打印此数组位置,否则k++,列清零。若X[k]>n则k自减进行回溯。
    思路已经很清楚具体了,可代码写出来还是有一点问题,问题出在有一个else之后没有加{},还有一个问题出在调用函数后没有return回去标记值。
    代码如下:

#include <stdio.h>
#include <math.h>
int place(int k);
int k=1,x[100]={
    
    0};
int main(){
    
    
	int n,sum=0;
	printf("请输入皇后数量:"); 
	scanf("%d",&n);
	while(k>0){
    
    
		x[k]++;
		while(x[k]<=n&&place(k)==0){
    
    
			x[k]++; 
		}
		if(x[k]<=n){
    
    
			if(n==k){
    
    
				//printf("成立\n");
				sum++;
			}
			else{
    
    
				k++;x[k]=0;
			}
		}
		else k--; 
	}
	printf("sum=%d\n",sum);
}
int place(int k){
    
    
	int i=1,t=1;
	while(i<k){
    
    
		if(abs(x[i]-x[k])==abs(i-k))
		t=0;
		if(x[i]==x[k])
		t=0;
		i++;
	}
	return t;
}

需打印皇后位置的代码如下:

#include <stdio.h>
#include <math.h>
int place(int k);
int k=1,x[100]={
    
    0};
int main(){
    
    
	int n,sum=0;
	printf("请输入皇后数量:"); 
	scanf("%d",&n);
	while(k>0){
    
    
		x[k]++;
		while(x[k]<=n&&place(k)==0){
    
    
			x[k]++; 
		}
		if(x[k]<=n){
    
    
			if(n==k){
    
    
				for(int i=1;i<=n;i++){
    
    
					for(int j=1;j<=n;j++){
    
    
						if(x[i]==j)
						printf("#");
						else printf("*");
					}
					printf("\n");
				}
				printf("\n");
				sum++;
			}
			else{
    
    
				k++;x[k]=0;
			}
		}
		else k--; 
	}
	printf("sum=%d\n",sum);
}
int place(int k){
    
    
	int i=1,t=1;
	while(i<k){
    
    
		if(abs(x[i]-x[k])==abs(i-k))
		t=0;
		if(x[i]==x[k])
		t=0;
		i++;
	}
	return t;
}

猜你喜欢

转载自blog.csdn.net/CSDN_Ysu/article/details/109075856