[kuangbin带你飞]专题一 简单搜索 A-棋盘问题 poj 1321

好久没做题感觉自己越来越菜了。。从头开始刷kuangbin叭
https://vjudge.net/contest/65959#overview
题目链接如上
poj 1321 棋盘问题
首先可以选用二维搜索

#include<stdio.h>
#include<iostream>
#include<string.h>
int a[30];
bool b[30];
int qipan[10][10];//2代表不可访问,0代表空可访问,1代表已经占位
int n,k;
int count=0;

int num;
void init()
{
    char c;

    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    for(int i=0;i<n;i++)
    {
        getchar();
        for(int j=0;j<n;j++)
        {
           scanf("%c",&c);
           if(c=='#') qipan[i][j]=0;
           else if(c=='.')
           {
               qipan[i][j]=2;
           }
        }
    }
    count=0;
}
void hs(int l,int m)
{
    if(m>=k)
    {
        count++;
        return;
    }

    for(int lnow=l;lnow<n;lnow++)
    {
        //if(a[lnow]==false)
            //{
                //a[lnow]=true;
                for(int i=0;i<=n-1;i++)
                {
                    if(b[i]==false&&qipan[lnow][i]==0)
                    {
                        b[i]=true;
                        qipan[lnow][i]=1;
                        hs(lnow+1,m+1);
                        b[i]=false;
                        qipan[lnow][i]=0;
                    }
                }
                //a[lnow]=false;
            //}
    }
}
/*void hs(int l)
{
    if(l>=n)
        return;
        if(num>=k)
        {
            count++;
            return;
        }
    for(int i=0;i<n;i++)
    {
        if(b[i]==false && qipan[l][i]==0)
        {
            b[i]=true;
            num++;
            hs(l+1);
            b[i]=false;
            num--;
        }
    }
}*/
using namespace std;
int main()
{
    while(scanf("%d%d",&n,&k) && (n!=-1 ||k!=-1))
    {
        init();
        hs(0,0);
        cout<<count<<endl;
    }
    return 0;
}

做题的时候要想明白这个回溯过程是不需要a数组的,因为按照行l来进行,就保证了行不会重复。
记得不断修改qipan
还有就是一个直接hs一个的,但是这个需要注意上面两个if的顺序,刚开始写的一直是反着的导致结果不够
(两种其实原理差不多叭感觉emmm。。。)

#include<stdio.h>
#include<iostream>
#include<string.h>
//int a[30];
bool b[30];
int qipan[10][10];//2代表不可访问,0代表空可访问,1代表已经占位
int n,k;
int count=0;

int num;
void init()
{
    char c;
    //memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    for(int i=0;i<n;i++)
    {
        getchar();
        for(int j=0;j<n;j++)
        {
           scanf("%c",&c);
           if(c=='#') qipan[i][j]=0;
           else if(c=='.')
           {
               qipan[i][j]=2;
           }
        }
    }
    count=0;
}
/*void hs(int l,int m)
{
    if(m>=k)
    {
        count++;
        return;
    }

    for(int lnow=l;lnow<n;lnow++)//这个位置保证了行不会超,但是下面那种是可能超的
    {
        //if(a[lnow]==false)
            //{
                //a[lnow]=true;
                for(int i=0;i<=n-1;i++)
                {
                    if(b[i]==false&&qipan[lnow][i]==0)
                    {
                        b[i]=true;
                        qipan[lnow][i]=1;
                        hs(lnow+1,m+1);
                        b[i]=false;
                        qipan[lnow][i]=0;
                    }
                }
                //a[lnow]=false;
            //}
    }
}*/
void hs(int l)
{

        if(num>=k)
        {
            count++;
            return;//当最后一个被安排在最后一行,l+1必定会超,这时候可能有答案的so。。
     
        }
    if(l>=n)
    return;
    for(int i=0;i<n;i++)
    {
        if(b[i]==false && qipan[l][i]==0)
        {
            b[i]=true;
            qipan[l][i]=1;
            num++;
            hs(l+1);
            qipan[l][i]=0;
            b[i]=false;
            num--;
        }
    }
    hs(l+1);//代表没有放置棋子,不修改num,但是行数加一
}
using namespace std;
int main()
{
    while(scanf("%d%d",&n,&k) && (n!=-1 ||k!=-1))
    {
        init();
        num=0;
        hs(0);
        cout<<count<<endl;
    }
    return 0;
}

注意DFS和BFS的使用场合,DFS适合求出路径和具体信息,BFD适合求出最短路径和长度。(别人博客说的,存)
https://www.cnblogs.com/joeylee97/p/6128310.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值