2016 UESTC Training for Search Algorithm & String A - Xiper的奇妙历险(1) 八皇后问题、dfs




A - Xiper的奇妙历险(1)

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

西历772002年。

在喵哈哈村,有一个无忧无虑的少年 Xiper Xiper。在贵族家庭长大的 Xiper ,每天无忧无虑地过着挠挠头,吹吹逼的快乐生活。

title

然而一天,一辆马车到达了xiper的家里。从马车上,走下一个优雅的年轻人。

“在下周日天,有何贵干!?”

title

原来在十年前, Xiper 的爹曾被日天的爹所救。于是在日天的爹死后,xiper的爹为了报恩,收养了日天。

日天不仅挠头比 Xiper 快,吹逼也比 Xiper 屌,很快 Xiper 的朋友们都被日天给拉拢了。日天的到来,结束了 Xiper 无忧无虑的日子。

俗话说得好,上帝给你关上了一扇门,同时也会给你打开一扇窗户。在机缘巧合之下,郁闷的 Xiper 偶遇了美丽的卿学姐,并与她坠入了爱河。

然而,这一切都被狡诈的日天看在眼里。一日,日天趁着卿学姐独自一人,强吻了卿学姐。

“你的初吻不是 Xiper 的,而是我周日天的!”

夺妻之仇,不过如此!忍无可忍的 Xiper 终于向日天发起了挑战。他要日天在 9 9 列的国际象棋盘上摆下 9 个皇后,并使九个皇后互相无法攻击的

所有方案!

日天万万没想到, Xiper 居然问他智力题。被智商碾压的日天当即吐出一口鲜血,倒地不起。

从此,日天不敢轻视 Xiper ,在表面上和 Xiper 和平相处。

那么问题来了,所有的方案到底是什么呢?

Input

一个数 SIZE SIZE (9<=SIZE<=9) ,代表棋盘的大小

Output

第一行输出一个数 N ,表示所有的方案数。

接下来 N 行,每行输出 SIZE 个数,第 i i个数 ai 表示在第 i i行第 ai 列放了皇后。

因为出题人懒得写spj,所以请按字典序输出每个方案。

Sample input and output

Sample Input Sample Output
8
///仅作为例子参考
92
1 5 8 6 3 7 2 4 
1 6 8 3 7 4 2 5 
1 7 4 6 8 2 5 3 
1 7 5 8 2 4 6 3 
(剩下88种请自行脑补)

Hint

如果任意两个皇后都不在同一行、同一列、同一斜线上,则是满足条件的方案。

只有一组测试数据。

由于出题人是个智障,输出答案时,每个方案最后一个数字后面要多输出一个空格再换行,不然似乎会PE...

Source

2016 UESTC Training for Search Algorithm & String


My Solution

八皇后问题


这里是九个皇后


逐行放置,则皇后肯定不会横向攻击,只需要检查纵向和两个斜向攻击即可


其中用 cur - C[cur] == j - C[j] || cur + C[cur] == j + C[j] 来判断是否有斜向攻击


用 C[cur] == C[j] 检查纵向攻击




然后每次 cur == n 的时候这一钟情况就完成了, 把这个C[0~n-1] 存储到ans[tot][i]里


最后全部返回了 就得到了所有答案


然后for for 打印即可

#include <iostream>
#include <cstdio>
using namespace std;

int n, tot, C[16];
// n == 9, tot == 352
int ans[352+8][9];

void _search(int cur)
{
    if(cur == n){
        tot++;
        for(int i = 0; i < n; i++){
            ans[tot][i] = C[i];
        }
    }
    else{
        for(int i = 1; i <= n; i++){        //!行数的表示用 1 ~ n, 下标还是 0 ~ n-1
            int ok = 1;
            C[cur] = i;                     //把第cur行的皇后放在第C[cur] = i列
            for(int j = 0; j < cur; j++){   //检查是否冲突
                if(C[cur] == C[j] || cur - C[cur] == j - C[j] || cur + C[cur] == j + C[j]){
                    ok = 0; break;
                }
            }
            if(ok) _search(cur+1);
        }
    }
}
//!HInt 每个方案最后一个数字后面要多输出一个空格再换行
int main()
{
    #ifdef LOCAL
    freopen("a.txt", "w", stdout);
    #endif // LOCAL
    tot = 0;
    scanf("%d", &n);
    _search(0);
    printf("%d\n", tot);
    for(int i = 1; i <= tot; i++){
        for(int j = 0; j < n; j++){
            printf("%d ", ans[i][j]);
        }
        printf("\n");
    }
    return 0;
}

Thank you!

                                                                                                                                               ------from ProLights









































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值