洛谷 八皇后

题目传送门

 好的满分方法:传送门

它讲的非常详细,仔细一看方法和我的差不多,不同点在于斜的两个标记和竖的标记它分别为这个开了三个数组,然后用来存这里是否已经被占领,然后递归完下一个再恢复,我本来也想这样的,但我只想到用一个二维数组的方法,这样是不可能回溯的,所以导致我最后一个数据超时而他没超时

通过这题的收获是,大的解决不了的时候化成小的,比如说我就应该再多建几个数组完成回溯的,可是我没有想到,很遗憾

自己的不ok87分方法:

ps.把没满分的方法放这是给自己以后看的,代码存博客园比存电脑硬盘好管理多了

思路:

第一次,可以选1,2,3,4,5,6

接下来,每一次选都不能处于前面子的攻击范围内,这个用sign标记,然后一直递归就好了

评析:

这个做法6~12都可以,但是当n=13时会超时,因为没有优化过,而且我没有想到怎么优化

然后中间除了个错误,以后都不写std::ios::sync_with_stdio(false)了,因为我根本只是照猫画虎,不懂这东西,很容易出错

#include<bits/stdc++.h>
using namespace std;
int ans=0,n;
int a[100],sign[100],t=0;

int f(int new_i)
{
    if(new_i==n+1)
    {
        if(t<3){
                for(int i=1;i<=n;i++)
                {
                    printf("%d ",a[i]);
                }
                printf("
");
        }
        ans++;
        t++;
        return 0;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=new_i-1&&new_i!=1;j++)
        {
            sign[a[j]]=1;
            int left=a[j]-(new_i-j);
            int right=a[j]+(new_i-j);
            if(left>=1)
                sign[left]=1;
            if(right<=n)
                sign[right]=1;
        }
        if(sign[i]!=1||new_i==1)
        {
            a[new_i]=i;
            memset(sign,0,sizeof(sign));
            f(new_i+1);
        }
        memset(sign,0,sizeof(sign));
    }
    return 0;
}

int main()
{
    scanf("%d",&n);
    f(1);
    printf("%d",ans);
}
给自己看的低分代码
原文地址:https://www.cnblogs.com/zyacmer/p/10090314.html