user-0 提问: 自己写的8皇后递归移位实现

回复:
user: user-0
content: #include "iostream"       using namespace std;       #include "time.h"        // sum用来记录皇后放置成功的不同布局数；upperlim用来标记所有列都已经放置好了皇后。       long sum = 0, upperlim = 1;             // 试探算法从最右边的列开始。       void test(long row, long ld, long rd)       {           if (row != upperlim)           {               // row，ld，rd进行“或”运算，求得所有可以放置皇后的列,对应位为0，               // 然后再取反后“与”上全1的数，来求得当前所有可以放置皇后的位置，对应列改为1               // 也就是求取当前哪些列可以放置皇后               long pos = upperlim & ~(row | ld | rd);                while (pos)    // 0 -- 皇后没有地方可放，回溯               {                   // 拷贝pos最右边为1的bit，其余bit置0                   // 也就是取得可以放皇后的最右边的列                   long p = pos & -pos;                                                                  // 将pos最右边为1的bit清零                   // 也就是为获取下一次的最右可用列使用做准备，                   // 程序将来会回溯到这个位置继续试探                   pos -= p;                                               // row + p，将当前列置1，表示记录这次皇后放置的列。                   // (ld + p) << 1，标记当前皇后左边相邻的列不允许下一个皇后放置。                   // (ld + p) >> 1，标记当前皇后右边相邻的列不允许下一个皇后放置。                   // 此处的移位操作实际上是记录对角线上的限制，只是因为问题都化归                   // 到一行网格上来解决，所以表示为列的限制就可以了。显然，随着移位                   // 在每次选择列之前进行，原来N×N网格中某个已放置的皇后针对其对角线                   // 上产生的限制都被记录下来了                   test(row + p, (ld + p) << 1, (rd + p) >> 1);                                             }           }           else              {               // row的所有位都为1，即找到了一个成功的布局，回溯               sum++;           }       }        int main(int argc, char *argv[])       {           time_t tm;           int n = 16;            if (argc != 1)               n = atoi(argv[1]);           tm = time(0);            // 因为整型数的限制，最大只能32位，           // 如果想处理N大于32的皇后问题，需要           // 用bitset数据结构进行存储           if ((n < 1) || (n > 32))                            {               printf(" 只能计算1-32之间\n");               exit(-1);           }           printf("%d 皇后\n", n);            // N个皇后只需N位存储，N列中某列有皇后则对应bit置1。           upperlim = (upperlim << n) - 1;                     test(0, 0, 0);           printf("共有%ld种排列, 计算时间%d秒 \n", sum, (int) (time(0) - tm));           system("pause");           return 0;       }    测试过最快的一个

user: user-1
content: 引用 1 楼 Benjaminzhou93 的回复:不知道这算不算高效，明天研究研究网络上写的算法 ps（怎么传源代码可复制图片，就是带颜色的那种）  这个八皇后高效问题，可以网上搜索下！很多的！  至于代码格式，在发贴或者编译回复的时候，上方有个添加代码格式的选择<>， 加载人头和笑脸之间的， 点击下c/c++，把想要添加的代码加中出现的[code]之间就好了！

user: user-0
content: 引用 3 楼 zhao4zhong1 的回复:仅供参考：（绝对不高效）#include <stdio.h> int d[8][8]; int n; void queen8(int L) {     int x,y;      if (8==L) {         n++;         printf("%d\n",n);         for (y=0;y<8;y++) {             for (x=0;x<8;x++) { //              printf("%d",d[y][x]);                 if (d[y][x]) printf("■");                 else         printf("□");             }             printf("\n");         }         return;     }     for (x=0;x<8;x++) {         for (y=0;y<L;y++) {             if  (              d[y][x      ]              || (x-(L-y)>=0 && d[y][x-(L-y)])              || (x+(L-y)< 8 && d[y][x+(L-y)]))                 break;         }         if (y>=L) {             d[L][x]=1;             queen8(L+1);             d[L][x]=0;         }     } } int main() {     int y,x;     for (y=0;y<8;y++) {         for (x=0;x<8;x++) {             d[y][x]=0;         }     }     queen8(0);     return 0; }  多了一种参考方案

user: user-2
content: 仅供参考：（绝对不高效）#include <stdio.h> int d[8][8]; int n; void queen8(int L) {     int x,y;      if (8==L) {         n++;         printf("%d\n",n);         for (y=0;y<8;y++) {             for (x=0;x<8;x++) { //              printf("%d",d[y][x]);                 if (d[y][x]) printf("■");                 else         printf("□");             }             printf("\n");         }         return;     }     for (x=0;x<8;x++) {         for (y=0;y<L;y++) {             if  (              d[y][x      ]              || (x-(L-y)>=0 && d[y][x-(L-y)])              || (x+(L-y)< 8 && d[y][x+(L-y)]))                 break;         }         if (y>=L) {             d[L][x]=1;             queen8(L+1);             d[L][x]=0;         }     } } int main() {     int y,x;     for (y=0;y<8;y++) {         for (x=0;x<8;x++) {             d[y][x]=0;         }     }     queen8(0);     return 0; }

user: user-0
content: 引用 6 楼 baipv008 的回复:试了下，求解耗时基本为0吧。时间全是花在输出上。 //*八皇后 void printQueen(int* queen,int top) { 	for(int j=0;j<top;j++) 	{ 		for(int i=0;i<8;i++) 			if(i==queen[j]) 				printf("Q"); 			else 				printf("."); 		printf("\n"); 	} 	printf("\n");  } int issolution(int* queen,int top) { 	for(int i=0;i<top;i++) 		for(int j=0;j<top;j++) 			if(j!=i) 			{ 				if(abs(i-j)==abs(queen[i]-queen[j]) || queen[i]==queen[j]) 					return 0; 			} 	return 1; } int main() { 	clock_t ct_begin, ct_end; 	ct_begin = clock();  	int queen[8],top=-1,count=0; 	queen[++top]=0; 	while(1) 	{ 		if(!issolution(queen,top+1)) 			queen[top]++; 		else if(top==7) 		{ //			printQueen(queen,top+1); 			queen[top]++; 			count++; //			getchar(); 		} 		else 			queen[++top]=0; 		while(queen[top]>=8) 		{ 			top--; 			if(top<0) 				break; 			queen[top]++; 		} 		if(top<0) 			break; 	} 	ct_end = clock(); 	printf("一共%d个解",count); 	printf("used time: %f\n", (double)(ct_end - ct_begin)/CLOCKS_PER_SEC );  	getchar(); }//*/ 收下了

user: user-0
content: 引用 5 楼 max_min_ 的回复:[quote=引用 1 楼 Benjaminzhou93 的回复:] 不知道这算不算高效，明天研究研究网络上写的算法 ps（怎么传源代码可复制图片，就是带颜色的那种）  这个八皇后高效问题，可以网上搜索下！很多的！  至于代码格式，在发贴或者编译回复的时候，上方有个添加代码格式的选择<>， 加载人头和笑脸之间的， 点击下c/c++，把想要添加的代码加中出现的[code]之间就好了！[/quote]好

user: user-3
content: 试了下，求解耗时基本为0吧。时间全是花在输出上。 //*八皇后 void printQueen(int* queen,int top) { 	for(int j=0;j<top;j++) 	{ 		for(int i=0;i<8;i++) 			if(i==queen[j]) 				printf("Q"); 			else 				printf("."); 		printf("\n"); 	} 	printf("\n");  } int issolution(int* queen,int top) { 	for(int i=0;i<top;i++) 		for(int j=0;j<top;j++) 			if(j!=i) 			{ 				if(abs(i-j)==abs(queen[i]-queen[j]) || queen[i]==queen[j]) 					return 0; 			} 	return 1; } int main() { 	clock_t ct_begin, ct_end; 	ct_begin = clock();  	int queen[8],top=-1,count=0; 	queen[++top]=0; 	while(1) 	{ 		if(!issolution(queen,top+1)) 			queen[top]++; 		else if(top==7) 		{ //			printQueen(queen,top+1); 			queen[top]++; 			count++; //			getchar(); 		} 		else 			queen[++top]=0; 		while(queen[top]>=8) 		{ 			top--; 			if(top<0) 				break; 			queen[top]++; 		} 		if(top<0) 			break; 	} 	ct_end = clock(); 	printf("一共%d个解",count); 	printf("used time: %f\n", (double)(ct_end - ct_begin)/CLOCKS_PER_SEC );  	getchar(); }//*/

user: user-0
content: 引用 1 楼 Benjaminzhou93 的回复:不知道这算不算高效，明天研究研究网络上写的算法 ps（怎么传源代码可复制图片，就是带颜色的那种） 我的奔腾cpu上大概需要1.5~1.9才能解的出来

user: user-0
content: 不知道这算不算高效，明天研究研究网络上写的算法 ps（怎么传源代码可复制图片，就是带颜色的那种）