Nn皇后问题,其实说白了就是排列,可以把整个棋盘,抽象成一个区间,就是排列了,这个棋子的位置,只需要求得它位置代表的数,那么就是填数,列就是位置。Simple!
所以关键是列即为位置,这个很好理解,那么位置有了,数从1开始也解决了,先把框架写出来,注意从1位置开始填。数也从1开始,那么可以写出来如排列的框架。
这里写一种暴力比较的方法。
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<fstream>
using namespace std;
int P[10];
int num;
bool test[10] = {false};
int countt;
void generate(int index) {
if(index == num + 1) {
int flag = 0;
for(int i = 1; i <= num; i++) {
for(int j = i+1; j <= num; j++) { //两两暴力比较
if(abs(i-j)==abs(P[i]-P[j])) {
flag = 1;
}
}
}
if(flag == 0) {
for(int i = 1; i <= num; i++) {
printf("%d",P[i]);
}
countt++;
printf("\n");
}
return;
}
for(int x = 1; x <= num; x++) {//
if(test[x]==false) {
test[x] = true;
P[index] = x;//index表示列,,x表示组合,即行的次序
generate(index+1);
test[x] = false;
}
}
}
int main() {
freopen("d://in.txt","r",stdin);
int N;
countt = 0;
while(scanf("%d",&N)!=EOF) {
while(N--) {
scanf("%d",&num);
generate(1);//从一开始p【i】
}
}
//输入
//1
//8
printf("%d",countt);
return 0;
}
问题 D: 八皇后
[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 32 MB
解决: 886提交: 1572统计
题目描述
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。
对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2…b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。
给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。
输入
第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1 <= b <= 92)
输出
输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。
样例输入 Copy
3
6
4
25
样例输出 Copy
25713864
17582463
36824175
这一题的nn皇后,是固定的8皇后,要求的是求第n种排列的方法,
把每种排列的数组用做一个整数存储,然后排序即可。。。(而且用的是回溯法,即跳过递归法)
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<fstream>
using namespace std;
int ans[92] = {0};//记录结果,去排序
int P[9] = {0}; //记录P下标的递归
int N = 8;
int countt;
bool flag[1000] = {false};
int P_ans[92]= {0};
int P_ans_count;
void create() {
int ans = 0;
for(int i = 1; i<=N; i++) {
int temp = P[i];
ans = ans * 10 + temp;
}
P_ans[P_ans_count++] = ans;
}
void generate(int index) {
if(index == N + 1) {
countt++;
create();
return;
}
for(int x = 1; x <= N; x++) {
//8行 即8个数来填入P
if(flag[x] == false) {//有可以拿的通行证再加以审核
int test = false;
//若此时3不行,就得把3的数a不放,for重新选个数b填入3位置!
for(int pre = 1; pre <= index-1; pre++) { //表示列 前面的列 即index
if(abs(pre-index)==abs(x-P[pre])) {//行别搞错,是填入的数!! p还没存
test = true;
break;
}
}
if(!test) {
P[index] = x;
flag[x] = true;
generate(index + 1);// 1 2 3 4 表示2到3
flag[x] = false;
}
}
}
}
int main() {
// freopen("d://in.txt","r",stdin);
int num;
// 8皇后
countt = 0;
P_ans_count = 0;
generate(1);//P开始填,填完就记录
// printf("%d\n",countt);
sort(P_ans,P_ans+92);
int KK;
scanf("%d",&KK);
while(KK--) {
scanf("%d",&num);
printf("%d\n",P_ans[num-1]);
}
return 0;
}