跳棋的挑战
呃呃,这题是一道经典的DFS题,就是个8皇后啊。
因为本人心虚,赶脚写的代码有点慢,就打了个表。
咳咳咳,说正题,这题说每行,每列,每斜边都至多有一个旗子,这不就是8皇后的标准题目吗,8皇后大家总会写吧。
恩,如果大家连把皇后都不会写的话,那就接着往下看。
先看一下8皇后的原题:
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法.
用深搜就可以解决了,先枚举每一行,然后判断能不能放,如果能放,就先放着,递归调用一下,等回溯的时候再拿起来。
关于这个判断能不能放,还有一点小技巧,行和列当然都很简单,但是斜行就不同了,斜行分两条,一条从左往右,一条从右往左,这里就直说了,这两条分别可以这样表示:
x1[deep-i+20] = 1,x2[deep+i] = 1
上代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
int ans,n,l[100],x1[100],x2[100],ans1[100],ans2[100] = {4,40,92,352,724,2680,14200,73712};
void print()
{
if(ans>3)return;
for(int i = 0;i<n;i++)std::cout<<ans1[i]+1<<" ";
std::cout<<std::endl;
}
void get_ans(int deep)
{
if(ans==3)return;
if(deep==n){ans++;print();return;}
for(int i = 0;i<n;i++)
{
if(l[i]==1||x1[deep-i+20]==1||x2[i+deep]==1)continue;
l[i] = 1;x1[deep-i+20] = 1;x2[deep+i] = 1;ans1[deep] = i;
// for(int i = 0;i<n;i++)std::cout<<l[i]<<" ";
// std::cout<<std::endl;
get_ans(deep+1);
l[i] = 0;x1[deep-i+20] = 0;x2[deep+i] = 0;
}
}
int main()
{
freopen("checker.in","r",stdin);
freopen("checker.out","w",stdout);
std::cin>>n;
get_ans(0);
std::cout<<ans2[n-6];
fclose(stdin);
fclose(stdout);
return 0;
}
随时随刻,当你想要颓废的时候,想想之前为何而来,当你想要放弃的时候,想想之前你为何坐在这里