⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 006.cpp

📁 包含两个文件
💻 CPP
字号:
#include <malloc.h>
#include <iostream.h>
#include <time.h>

//程序生成一个动态二维数组作为棋盘.
//实现时采用加标签的方法:当在一个位置放入一个皇后后,将再放入皇后会与此位置产生攻击的地方
//加上标签,即给这些位置加上1.
//当为一个皇后找位置时,从第一列往后找,如一位置为0,则改位置放入皇后后不会与已放入的皇后攻击.
//如这列全不为0,则此路径无解,反回,撤消放入前一个皇后时所加的1,并从该位置往后找0位置.

void main()
{
	cout<<"本程序功能是求解皇后问题"<<endl;
	cout<<"   2005级     徐立钧      "<<endl;
	cout<<"\n-------------------------------------\n"<<endl;

    unsigned int number;//解的数目
	int n;//皇后数
    char hh;

    int i,j,m,k;
	int *wei;//指向一个用于回溯的数组	
	int **p;//指向动态二维数组
    clock_t start, end;

	do{

	cout<<"请输入皇后个数:"<<endl;
	cin>>n;


    //-------------------初始化-----------------
    number=0;
    wei=new int[n+1];

	p=new int* [n+1];

	for(i=1;i<=n;i++)
	{
		p[i]=new int[n+1];
	}

	for(i=1; i<=n; i++)
		for(j=0;j<=n;j++)
			p[i][j]=0;


   //---------------求解------------------------
	
	cout<<"开始求解..."<<endl;
	start=clock();

	for (j=1; j<=n/2; j++)
	{
        i=1;
		wei[i]=j;
       
	   //放置此位置后,给后面会产生冲突的位置加上标签
       for (k=0; k<n-i; k++)  p[n-k][j]++;
	   for (k=1; k<=j-1; k++)  p[i+k][j-k]++;
	   for (k=1; k<=n-j; k++)  p[i+k][j+k]++;
  
        ++i;
		k=1;

        while( i>1 )	
		{
	        while ((k <= n) && (p[i][k] != 0)) k++;				
		    if (k <= n)
			{
			     wei[i] = j = k;
		         //放置此位置后,给后面会产生冲突的位置加上标签
                for (k=0; k<n-i; k++)  p[n-k][j]++;
				m=j-1<n-i? j-1:n-i;
	            for (k=1; k<=m; k++)  p[i+k][j-k]++;
                m=n-j<n-i? n-j:n-i;
	            for (k=1; k<=m; k++)  p[i+k][j+k]++;
                 k=1;
			     ++i;
			}
			
		    else
			{   //找不到能放的位置
                i--;//后退
			   
                 j = wei[i];
	             //撤除所加标签
				 for (k=0; k<n-i; k++)  p[n-k][j]--;
                 m=j-1<n-i? j-1:n-i;
	             for (k=1; k<=m; k++)  p[i+k][j-k]--;
                 m=n-j<n-i? n-j:n-i;
	             for (k=1; k<=m; k++)  p[i+k][j+k]--;
			     k=wei[i]+1;
			}
		    if (i > n) 
			{   //是一个解
			    number++;
			    i -=2;//退回
				j = wei[i];
                //撤除所加标签
	            for (k=0; k<n-i; k++)  p[n-k][j]--;
                m=j-1<n-i? j-1:n-i;
	            for (k=1; k<=m; k++)  p[i+k][j-k]--;
                m=n-j<n-i? n-j:n-i;
	            for (k=1; k<=m; k++)  p[i+k][j+k]--;
		    	k=wei[i]+1;
			}
		}
	}

   number*=2;

    //若为奇数的处理
	if(n%2)
	{
        i=1;
		wei[i]=j=n/2+1;
       //放置此位置后,给会产生冲突的位置加上标签
       for (k=0; k<n-i; k++)  p[n-k][j]++;
       m=j-1<n-i? j-1:n-i;
	   for (k=1; k<=m; k++)  p[i+k][j-k]++;
       m=n-j<n-i? n-j:n-i;
	   for (k=1; k<=m; k++)  p[i+k][j+k]++;
  
        ++i;
		k=1;
        while(i > 1)
		{
	        while ((k <= n) && (p[i][k] != 0)) k++;		
		    if (k <= n)
			{
			     wei[i] = j = k;
		        //放置此位置后,给会产生冲突的位置加上标签
                for (k=0; k<n-i; k++)  p[n-k][j]++;
                m=j-1<n-i? j-1:n-i;
	            for (k=1; k<=m; k++)  p[i+k][j-k]++;
                m=n-j<n-i? n-j:n-i;
	            for (k=1; k<=m; k++)  p[i+k][j+k]++;
                 k=1;
			     ++i;
			}
		    else
			{   //找不到能放的位置
                i--;
			   //撤除所加标签
				j=wei[i];
	            for (k=0; k<n-i; k++)  p[n-k][j]--;
                m=j-1<n-i? j-1:n-i;
	            for (k=1; k<=m; k++)  p[i+k][j-k]--;
                m=n-j<n-i? n-j:n-i;
	            for (k=1; k<=m; k++)  p[i+k][j+k]--;
			    k=wei[i]+1;
			}
		    if (i > n) 
			{
			    number++;
			    i -=2;
				j=wei[i];
                //撤除所加标签
	            for (k=0; k<n-i; k++)  p[n-k][j]--;
                m=j-1<n-i? j-1:n-i;
            	for (k=1; k<=m; k++)  p[i+k][j-k]--;
                m=n-j<n-i? n-j:n-i;
	            for (k=1; k<=m; k++)  p[i+k][j+k]--;
		    	k=wei[i]+1;
			}
		}
	}

	end=clock();

    cout<<"OK!  求解完毕! "<<endl;
	cout<<" "<<n<<" 皇后共找到 "<<number<<" 个解"<<endl;
    cout<<"共用时 "<<end-start<<" 豪秒"<<endl;

    delete []p;
    delete []wei;
	p=NULL;
	wei=NULL;

	cout<<"\n是否继续?(y/n):"<<endl;
	cin>>hh;

	}while(hh=='y');


	char cc;
	cout<<"请击一键退出"<<endl;
	cin>>cc;

}




	




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -