【NOJ1006】【算法实验二】【回溯算法】堡垒问题_方格类数据表示方法


1006.堡垒问题

时限:1000ms 内存限制:10000K  总时限:3000ms

描述

城堡是一个4×4的方格,为了保卫城堡,现需要在某些格子里修建一些堡垒。城堡中的某些格子是墙,其余格子都是空格,堡垒只能建在空格里,每个堡垒都可以向上下左右四个方向射击,如果两个堡垒在同一行或同一列,且中间没有墙相隔,则两个堡垒都会把对方打掉。问对于给定的一种状态,最多能够修建几个堡垒。

输入

每个测例以一个整数n(1<=n<=4)开始,表示城堡的大小。

接下来是n行字符每行n个,‘X’表示该位置是墙,‘.’表示该位置是空格。

n等于0标志输入结束。

输出

扫描二维码关注公众号,回复: 3457099 查看本文章

每个测例在单独的一行输出一个整数:最多修建堡垒的个数。


#include <iostream>

using namespace std;

int n;      //城堡大小
int a[4][4];    //城堡方格,1==墙,0==空,-1==堡垒
                //左上角为方格[0,0]

int mcnt;   //最大堡垒个数
int cnt;    //当前已建堡垒个数

void dfs(int m);        //回溯深搜
bool ok(int i,int j);   //判断方格[i,j]能否放置堡垒

int main()
{
    cin>>n;
    while(n){
        char c;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                cin>>c;
                if(c=='X')      //墙
                    a[i][j]=1;
                else            //空
                    a[i][j]=0;
            }
        }
        //初始化
        mcnt=0;
        cnt=0;

        dfs(0);

        cout<<mcnt<<endl;

        cin>>n;
    }

    return 0;
}

void dfs(int m)     //判断序号为m的方格
{
    if(m==(n*n)){       //搜到最后一个方格
        if(mcnt<cnt)    //更新最大值
            mcnt=cnt;
    }
    else{
        int i=m/n;
        int j=m%n;
        if(ok(i,j)){     //若方格m内可以修建堡垒
            a[i][j]=-1;
            cnt++;
            dfs(m+1);
            cnt--;
            a[i][j]=0;
        }
        dfs(m+1);
    }
}

//函数功能:判断方格[i,j]内能否放置堡垒
//不能放置条件:
//1.本方格是墙
//2.本方格的上方或左方有堡垒(中间无墙相隔)
//因为是按序号顺序搜索方格,因此不必判断下方或右方(还未放置,必无堡垒)
bool ok(int i,int j)
{
    int x,y;
    if(a[i][j]==1)  return false;   //本方格是墙

    for(x=i-1,y=j;x>=0;x--){ //向上找
        if(a[x][y]==1)  break;
        if(a[x][y]==-1) return false;
    }

    for(x=i,y=j-1;y>=0;y--){ //向左找
        if(a[x][y]==1)  break;
        if(a[x][y]==-1) return false;
    }

    return true;
}

【后记】

1.做了几道回溯,深深感觉dfs简直就是套路,里面多半是下面这种格式:

if (m==n)

    {......}

else

    {.......}

2.既然算法是套路,那么麻烦主要在于如何表示数据

一般来说,方格类数据用二维数组表示,每个方格有两个名字:序号m和位置[ i , j ]

默认左上角为序号0,位置为[ 0 , 0 ],如下图所示:

猜你喜欢

转载自blog.csdn.net/qq_41727666/article/details/82911994