跳棋的挑战

来源:互联网 发布:linux ping指定接口 编辑:程序博客网 时间:2024/04/28 12:45

呃呃,这题是一道经典的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;}
原创粉丝点击