专题8:dfs和bfs

问题 B: 三角棋盘上的N皇后

时间限制: 1 Sec  内存限制: 128 MB
[提交] [状态]

题目描述

下图,就是一个大小为6的三角形棋盘:
 
Figure 1给出的是皇后攻击范围的示例——每个皇后有三个方向可以自由攻击。
Figure 2给出的是在一个三角形棋盘上的不能互相攻击的4个皇后。
现在,你有一个三角形棋盘,棋盘上已经放置了几个互相不能攻击的皇后,请问棋盘上最多还能放多少个皇后,使得她们仍然不能互相攻击;并求出有多少种方案可以放这么多皇后。编程输出这两个数。

 

输入

第一行一个数字N,代表棋盘的大小。

接下来N行,第i行有i个字符。表示棋盘第i行的状态,‘.’表示空,‘*’表示有皇后。

 

输出

两行,每行一个数字,分别为在原来的棋盘上最多能放的皇后数量,和放置这么多皇后的方案种数。

样例输入 Copy

2
.
..

样例输出 Copy

1
3

提示

1<=N<=13

 

 

[提交][状态]

先看看经典的八皇后源代码 


#include <stdio.h>
int Queenes[8]={0},Counts=0;
int Check(int line,int list){    //遍历该行之前的所有行
    for (int index=0; index<line; index++) {    //挨个取出前面行中皇后所在位置的列坐标
       
        int data=Queenes[index];   

        if (list==data) {                 //如果在同一列,该位置不能放
            return 0; 
        }
        if ((index+data)==(line+list)) {   //如果当前位置的斜上方有皇后,在一条斜线上,也不行
            return 0;
        }
        if ((index-data)==(line-list)) {   //如果当前位置的斜下方有皇后,在一条斜线上,也不行
            return 0;
        }
    }
    return 1;  
    //如果以上情况都不是,当前位置就可以放皇后
}

//输出语句

void print()
{
    for (int line = 0; line < 8; line++)
   {
       int list;
        for (list = 0; list < Queenes[line]; list++)
            printf("0");
        
        printf("#");
       
        for (list = Queenes[line] + 1; list < 8; list++)
            printf("0");

        printf("\n");
   }
  printf("================\n");
}

void eight_queen(int line){   //在数组中为0-7列

    for (int list=0; list<8; list++) {

        if (Check(line, list)) {   //对于固定的行列,检查是否和之前的皇后位置冲突

            Queenes[line]=list;  //不冲突,以行为下标的数组位置记录列数
            if (line==7) {   //如果最后一样也不冲突,证明为一个正确的摆法
                Counts++;  //统计摆法的Counts加1
                print(); //输出这个摆法
                Queenes[line]=0;  //每次成功,都要将数组重归为0
                return;
             }

           eight_queen(line+1); //继续判断下一样皇后的摆法,递归
           Queenes[line]=0; //不管成功失败,该位置都要重新归0,以便重复使用。

        }

   }

}

int main() {

    //调用回溯函数,参数0表示从棋盘的第一行开始判断

    eight_queen(0);

    printf("摆放的方式有%d种",Counts);

    return 0;

}

这道题没有什么奇特之处 ,偷学长的代码

#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define se second
#define fi first
const int N=1e6+5;
const ll mod=1e9+7;
typedef pair<int,int> pp;
char g[15][15];
int n,res[200],a[15],b[15],c[15];
 
void dfs(int cnt,int x,int y)
{
    if(x<y){
        x++,y=1;
    }
    if(x>n){
        res[cnt]++;
        return ;
    }
    if(!a[x]&&!b[y]&&!c[x-y]){
        a[x]=b[y]=c[x-y]=1;
        dfs(cnt+1,x,y+1);
        a[x]=b[y]=c[x-y]=0;
    }dfs(cnt,x,y+1);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%s",g[i]+1);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            if(g[i][j]=='*'){
                a[i]=1;
                b[j]=1;
                c[i-j]=1;
            }
        }
    }
    dfs(0,1,1);
    for(int i=100;i>=0;i--){
        if(res[i]){
            printf("%d\n%d\n",i,res[i]);
            return 0;
        }
    }
    return 0;
}
 

 我不知道这个代码和上面有什么区别,居然错了

#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define se second
#define fi first
const int N=1e6+5;
const ll mod=1e9+7;
int n,res[200],a[20],b[20],c[20];
void dfs(int cnt,int x,int y)
{
    if(x<y) //换行
    {
        x++;
        y=1;
    }
    if(x>n)
    {
        res[cnt]++;
        return ;
    }
    if(!a[x]&&!b[y]&&!c[x-y])
    {
        a[x]=b[y]=c[x-y]=1;
        dfs(cnt+1,x,y+1);
        a[x]=b[y]=c[x-y]=0;
    }
    dfs(cnt,x,y+1);
 
}
int main()
{
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
         string s;
        cin>>s;
        for(int j=1; j<=i; j++)
        {
            if(s[j-1]=='*')
            {
                a[i]=1;
                b[i]=1;
                c[i-j]=1;
            }
        }
    }
    dfs(0,1,1);
    for(int i=100; i>=0; i--)
    {
        if(res[i])
        {
            printf("%d\n%d\n",i,res[i]);
           return 0;
        }
    }
    return 0;
}
 
 
/**************************************************************
    Problem: 14886
    User: 2019UPC110
    Language: C++
    Result: 答案错误
****************************************************************/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值