P1219 八皇后问题 2021.6.26

八皇后问题是一个经典的DFS问题
其思路:

每一行作为一层,每一层从第一个位置开始寻找,若能找到满足条件的位置,记录下当前位置,然后

(1)若当前行为最后一行,则将已经找到的所有位置输出
(2)若当前行不为最后一行,则dfs进入下一层

若当前层寻找完了(不管有没有找到合适的点),则return返回上一层。

我在处理题目时时遇到的一个问题就是,如何高效的处理不满足条件的位置。也就是说,在遍历当前层时,我需要知道这个位置合适与否。而判断这个位置合适与否,是与上面的每个层都有关,但倘若每到一个点都将上面层的位置关系传递下来的话,会很吃时间,最终导致TLE。于是就利用一个数组来专门存储这个位置可以或是不可以放皇后——这个原理是在每一层中,每个点的可以放与不可以放的位置是相同的。

出现过的bug:
代码在写完后出现的bug有
1、 a [ i ] 是用来遍历这个数组的,结果写成 a [ n ] 导致数组没有用到。
2、 i 与 j 都是用来数组遍历的辅助变量,结果弄混了, j 写成了 i (这还不是第一次犯这种错误了,必须牢记)
3、不满足条件的为位置的条件我少写了一个。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
int number=3;
int sum=0;
void dfs(int n,int floor,int *location);
int main() {
    int n;
    scanf("%d",&n);
    int location[n];
    for (int i=0; i<n; i++) {
        location[i]=-1;
    }
    dfs(n, 0, location);
    printf("%d",sum);
    return 0;
}

void dfs(int n,int floor,int *loction){
//        for (int j=0; j<n; j++) {
//            printf("%d ",loction[j]+1);
//        }
//        printf("\n");
        int a[n];
        //这个数组用来判断这个位置到底能不能放皇后
        for (int i=0; i<n; i++) {
            a[i]=1;
        }//这个循环初始化数组
        
        for (int i=0; i<floor; i++) {   //i代表当前遍历的楼层
            a[loction[i]]=0;
            if (loction[i]+floor-i<=n-1) {
                a[loction[i]+floor-i]=0;
            }
            if (loction[i]-(floor-i)>=0) {
                a[loction[i]-(floor-i)]=0;
            }
        }//这个循环表示将不满足条件的位点给排除掉
        
        for (int i=0; i<n; i++) {
            if (a[i]==1&&floor!=n-1) {
                loction[floor]=i;
                dfs(n, floor+1, loction);
            }
            if (a[i]==1&&floor==n-1) {
                loction[floor]=i;
                sum++;
                if(number){
                    number--;
                for (int j=0; j<n; j++) {
                    printf("%d ",loction[j]+1);
                }
                    printf("\n");
                }
            }
        }//这个循环表示遍历当前楼层所有可以放置的点
        return;
    
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值