/*这次用全排列来求了,横竖都不能相同,那么就是n个元素全排列的问题,然后从中找出对角线上也不符合的,剩下的就都符合了. 自己想了一个全排列的算法,不知道还有没有更高效的.原理是插入算法,每次插入,右边的元素右移,左边的不变,这个可以用过改下标数组来实现.然后,由于下标与元素的一一对应,元素的排列就等于下标的排列,不用再倒换过来了. 现在8皇后问题,考虑到对称性,可以下降到15毫秒了*/ #include <iostream.h> #include <math.h> #include<time.h> #include<fstream.h> int Qcount=0; bool *Flag1; bool *Flag2; bool *Flag3; //检查是否冲突,冲突返回true,不冲突false void InitFlags(); bool CheckExist(int * H) { int offset=Qcount-1; InitFlags(); //H的个数等于Qcount int tmpidx; for(int i=0;i<Qcount;i++) { tmpidx=(i+H[i]);//表示x+y if (Flag2[tmpidx]==false) { Flag2[tmpidx]=true; } else { return true; } } for( i=0;i<Qcount;i++) { tmpidx=(i-H[i]+offset);//表示x-y+offset if (Flag3[tmpidx]==false) { Flag3[tmpidx]=true; } else { return true; } } return false; } void Init() { cout<<"输入皇后的个数"<<endl; cin>>Qcount; Flag1=new bool[Qcount];//标志位大小表示对应y先不相等 Flag2=new bool[2*Qcount-1];//表示x+y, Flag3=new bool[2*Qcount-1];//表示x-y+offset } void InitFlags() { for (int j=0;j<2*Qcount-1;j++) { // Flag1[j%Qcount]=false;//初始化成没用过 Flag2[j]=false; Flag3[j]=false; } } unsigned int factorial(unsigned int n) { unsigned int result=1; for (unsigned int i=2;i<=n;i++) { result*=i; } return result; } void main() { int result=0; Init(); clock_t ts=clock(); int *index=new int[Qcount]; unsigned int jiecheng=factorial(Qcount)/2; for (unsigned int i=0;i<jiecheng;i++) { int tmp=i; for (int k=0;k<Qcount;k++) { index[k]=0; } for (int item=1;item<Qcount;item++) { int idx=tmp%(item+1); for (int j=0;j<item;j++) { if (index[j]>=idx) { index[j]++; } } index[item]=idx; tmp/=(item+1); } if (!CheckExist(index)) { ++result; } for (int j=0;j<Qcount;j++) { if(index[j]==Qcount-1-index[Qcount-1]) index[j]=index[Qcount-1],index[Qcount-1]=Qcount-1-index[Qcount-1]; //cout<<index[j]<<' '; } if (!CheckExist(index)) { ++result; } } delete [] index; clock_t te=clock(); cout<<"共"<<result<<"组解,用时"<<te-ts<<"毫秒"<<endl; delete [] Flag1; delete [] Flag2; delete [] Flag3; }