描述
题目描述
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2…b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。 给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。
输入描述:
每组测试数据占1行,包括一个正整数b(1 <= b <= 92)
输出描述:
输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。
示例1
输入
1
输出
15863724
分析
首先得找到全部92种排列方式,然后就可以进行排序输出了。
要找到全部方式,就是 经典的八皇后部分
用x[i]表示放在第i行的第x[i]个位置,其中1<=i<=8 1<=x[i]<=8;
初始化x[i]都为0
从第一行开始尝试,如果放在第j列的位置可以的话,就递归的去判断第二行,直到第8行以后,可以输出答案,这里为了便于处理用字符串记录,后面又转化为整数;
判断位置是否合法即当前第k行的x[k]跟前面的x[i],i< k都不相同,也就是不在同一列;
另外abs(k-i)==abs(x[k]-x[i])则判断是否在同以斜线(斜率为1)
可以想象是在回溯的遍历一棵八叉树
代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
vector<string> anss;
vector<long long> nums;
int x[10];
int sum = 0;
bool place(int k)
{
for (int i = 1; i <k; i++)
if (x[k] == x[i] || abs(k - i) == abs(x[k] - x[i]))return false;
return true;
}
void quene(int t)
{
if (t>8)
{
sum++;
string temp = "";
for (int i = 1; i <= 8; i++)
{
char c = x[i] + '0';
temp = temp + c;
}
//cout << temp << "\n";
anss.push_back(temp);
}
else {
for (int i = 1; i <= 8; i++)
{
x[t] = i;
if (place(t))quene(t + 1);
}
}
}
long long str2ll(string str)
{
long long sum1 = 0;
for (int i = 0; i<str.length(); i++)
sum1 = sum1 * 10 + str[i] - '0';
return sum1;
}
void sortTheOrder()
{
//cout << sum << "\n";
for (int i = 0; i<anss.size(); i++)
nums.push_back(str2ll(anss[i]));
sort(nums.begin(), nums.end());
}
int main()
{
for (int i = 1; i <= 8; i++)x[i] = 0;
int b;
quene(1);
sortTheOrder();
while (cin >> b)
{
cout << nums[b - 1] << "\n";
}
}