题目链接
思路:
-
第一次做m皇后问题,用了深搜,TLE。注意这里的深搜可以逐列搜索,而深度也无需记录,因为可以用列数充当深度。dfs() 只有列数一个参数。并且这里的 flip() 比较特殊,我使用的方法是记录一个三维的标记数组,第一维代表已经填充的皇后造成的标记,所以每次翻转要用
memcpy(rem[y] , rem[y-1] , sizeof(rem[y-1]));
以便回溯时消除标记(即避免对既得结果直接操作)。
-
对了,在证明里面终于看到了主对角编号(i-j+m) 和 副对角编号(i+j-1) 的概念,并且用四个编号全部唯一来证明,挺有意思的。
代码:
- 深搜代码:TLE
//TLE
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 305;
int n;
bool rem[maxn][maxn][maxn];//remark
bool flag;
int que[maxn];
void init(){
memset(rem , false , sizeof(rem));//不能放的格子置 1
flag = false;
}
void flip(int x,int y){
que[y] = x;
memcpy(rem[y] , rem[y-1] , sizeof(rem[y-1]));
for(int i=1 ; i<=n ; i++)
rem[y][i][y] = rem[y][x][i] = true;
for(int i=x , j=y ; i>=1 && j>=1 ; i-- , j--)
rem[y][i][j] = true;
for(int i=x , j=y ; i<=n && j<=n ; i++ , j++)
rem[y][i][j] = true;
for(int i=x , j=y ; i<=n && j>=1 ; i++ , j--)
rem[y][i][j] = true;
for(int i=x , j=y ; i>=1 && j<=n ; i-- , j++)
rem[y][i][j] = true;
return ;
}
void dfs(int y){
if(flag)
return ;
if(y > n){
flag = true;
return ;
}
for(int x=1;x<=n;x++){
if(y != 1)
if(rem[y-1][x][y])
continue;//这里已经不能放了就换下一行
flip(x,y);dfs(y + 1);
if(flag)
return ;
}
return ;
}
void output(){
for(int j=1;j<=n;j++)
if(j != n)
cout<<que[j]<<' ';
else
cout<<que[j]<<endl;
return ;
}
int main(){
while(cin>>n && n){
init();
dfs(1);
output();
}
return 0;
}
- 板子:652K 0MS
//652K 0MS
#include <iostream>
using namespace std;
void print(int l , int r){
for(int i=l;i<=r;i+=2)
cout<<i<<' ';
return ;
}
int main(){
int m;
while(cin>>m && m){
if(m%6 != 2 && m%6 != 3){
//A1、A2 分为 m奇、m偶
if(m%2){
print(2 , m-1);
print(1 , m) ;
}
else{
print(2 , m) ;
print(1 , m-1);
}
}
else{
int n = m/2;
//B1、B2、B3、B4
//按 m、n的奇偶性分为四组
if(m%2){
if(n%2){
print(n , m-2);
print(1 , n-2);
print(n+3 , m-1);
print(2 , n+1);
print(m , m );
}
else{
print(n , m-1);
print(2 , n-2);
print(n+3 , m-2);
print(1 , n+1);
print(m , m );
}
}
else{
if(n%2){
print(n , m-1);
print(1 , n-2);
print(n+3 , m );
print(2 , n+1);
}
else{
print(n , m );
print(2 , n-2);
print(n+3 , m-1);
print(1 , n+1);
}
}
}
}
return 0;
}