P1331 海战
https://www.luogu.com.cn/problem/P1331
题意
- 有一个 r x c的矩阵,停放矩形的船只
- 两个船停放,不能相邻。
- 求不相邻的船的个数。
想法
-
DFS+染色求联通块
- 先判断停放位置是否合适
- 再DFS染色求联通块
-
难点在于:
-
判断船停放的位置是否合适。不合适,就不用dfs染色
-
判断方法为,如果不合适一定存在这样的格式。也就是说船的部分呈现L形。
-
# # . # 或 # # # . 或 # . # # 或 . # # #
-
-
//
// Created by majoe on 2020/5/31.
//P1331 海战
//dfs做
#include <bits/stdc++.h>
using namespace std;
int dx[4]={0,0,1,-1};//横轴4方向数组
int dy[4]={1,-1,0,0};//纵轴4方向数组
int c,r,mp[1001][1001];
int cnt;
bool isOK(int x , int y){
int t = 0;
if(mp[x][y] == 1) t++;
if(mp[x+1][y] == 1) t++;
if(mp[x][y+1] == 1) t++;
if(mp[x+1][y+1] == 1) t++; // 摆放不能是L形状
if( t == 3) //L形状
{
return false;
}
return true;
}
//染色求联通块
void dfs(int x,int y){
if(!mp[x][y] || x < 1 || y < 1 || x > r || y > c) return;//越界或者没船
mp[x][y] = 0; //染色
for (int i = 0; i < 4; ++i) {
int tx = x + dx[i];
int ty = y + dy[i];
dfs(tx,ty);
}
return;
}
int main(){
cin >> r >> c;
char t;
for (int i = 1; i <= r; ++i) {
for (int j = 1; j <= c; ++j) {
cin >> t;
if(t == '.')mp[i][j]=0;
else mp[i][j]=1;//有船的地方为1
}
}
//判断都是否合规
for (int i = 1; i <= r; ++i) {
for (int j = 1; j <= c; ++j) {
if (i < r && j < c && !isOK(i,j)){
cout << "Bad placement.";
return 0;
}
}
}
//之后都是摆放正确的
for (int i = 1; i <= r; ++i) {
for (int j = 1; j <= c; ++j) {
if(mp[i][j]){
dfs(i,j); //dfs涂色,找联通块
cnt++; // 联通块的个数
}
}
}
printf("There are %d ships.",cnt);
return 0;
}