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

本文详细解析了POJ1321棋盘问题的回溯算法解决方案,通过二维搜索实现,重点介绍了如何利用回溯算法寻找所有可能的棋子放置方案,包括初始化棋盘状态、递归搜索和条件判断等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

好久没做题感觉自己越来越菜了。。从头开始刷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

### 关于 kuangbin ACM 算法竞赛培训计划 #### 数论基础专题介绍 “kuangbin专题十四涵盖了数论基础知识的学习,旨在帮助参赛者掌握算法竞赛中常用的数论概念和技术。该系列不仅提供了丰富的理论讲解,还推荐了本详细的书籍《算法竞赛中的初等数论》,这本书包含了ACM、OI以及MO所需的基础到高级的数论知识点[^1]。 #### 并查集应用实例 在另个具体的例子中,“kuangbin”的第五个专题聚焦于并查集的应用。通过解决实际问题如病毒感染案例分析来加深理解。在这个场景下,给定组学生及其所属的不同社团关系图,目标是从这些信息出发找出所有可能被传染的学生数目。此过程涉及到了如何高效管理和查询集合成员之间的连通性问题[^2]。 #### 搜索技巧提升指南 对于简单搜索题目而言,在为期约两周的时间里完成了这部分内容的学习;尽管看似容易,但对于更复杂的状况比如状态压缩或是路径重建等问题,则建议进步加强训练以提高解题能力[^3]。 ```python def find_parent(parent, i): if parent[i] == i: return i return find_parent(parent, parent[i]) def union(parent, rank, x, y): rootX = find_parent(parent, x) rootY = find_parent(parent, y) if rootX != rootY: if rank[rootX] < rank[rootY]: parent[rootX] = rootY elif rank[rootX] > rank[rootY]: parent[rootY] = rootX else : parent[rootY] = rootX rank[rootX] += 1 # Example usage of Union-Find algorithm to solve the virus spread problem. ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值