DFS(海战)

题目链接:P1331 海战 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1001;
char s[maxn][maxn];//保存地图的数组 
int n,m,ans=0;
int book[maxn][maxn];//标记数组 
int dx[]={1,-1,0,0};//方向数组 
int dy[]={0,0,1,-1};
bool judge(int x,int y) {//判断是否越界 
    if(x>=1&&x<=n&&y>=1&&y<=m)
        return true;
    return false;
}
bool find() {
    for(int i=1;i<=n;i++) {//因为i+1和j+1,所以这里的范围是i<n,j<m 
        for(int j=1;j<=m;j++) {
            int sum=0;
            if(!judge(i,j))//越界判断,如果越界,直接跳过此点,进入下一个点 
                continue;
            if(s[i][j]=='#')
                sum++;
            if(s[i+1][j]=='#')
                sum++;
            if(s[i][j+1]=='#')
                sum++;
            if(s[i+1][j+1]=='#')
                sum++;
            if(sum==3)//此时无法构成长方形 
                return false;    
        }
    }
    return true;
}
void dfs(int x,int y) {
    book[x][y]=1;//访问过的,标记为1 
    for(int k=0;k<4;k++) {//四个方向搜索 
        int tx=x+dx[k];
        int ty=y+dy[k];
        if(s[tx][ty]=='#'&&book[tx][ty]==0&&judge(tx,ty))//如果是船,同时还未访问过,并且不越界 
            dfs(tx,ty);//继续下一个点的搜索 
    }
}
int main() {
    memset(book,0,sizeof(book));//标记数组清零 
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf(" %c",&s[i][j]);//%前面的空格用来确保输入的完整 
    if(!find()) {//无法构成船只 
        printf("Bad placement.\n");
        return 0;
    }
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=m;j++) {
            if(s[i][j]=='#'&&book[i][j]==0) {//开始搜索 
                dfs(i,j);
                ans++;
            }
        }
    }
    printf("There are %d ships.\n",ans);
    return 0;
}

思路:模拟,主要是判断船是否合法,当#=3时不可能是船,特判一下,同时写好边界判断,然后进行dfs即可

如果图是不合法的,一定存在下面几种结构:

##

.#或

.#

##或

#.

##或

##

#.

(特判原因)

posted @ 2023-10-09 16:05  荧惑守心~  阅读(19)  评论(0编辑  收藏  举报