络谷 P1331 海战
Get to point first. The article comes from LawsonAbs
。
0.总结
0.1 如何判断船只合法?
利用深搜时记录下的信息结合题意设置判断规则,详见2.2
1.题目
请点击链接。
2.思想
2.1 如何得到船只
这部分直接dfs 即可,然后就把得到的船只用vis数组标记一下,下次不再访问了,但问题就是如何判断这次深搜的船只是两只或多只船只的“组合品”,即题目中所说的Bad placement?请往下看。
2.2如何判断船只合法
方形的定义是:“长方形和正方形统称为方形”。可以粗略的将方形的定义看作是矩形。所以,我们需要判断我们当前深搜得到的图形是否是矩形即可。这个也很好想到,矩形的特点就是很规整。(行的长度与列的长度固定)。这样我们就可以遍历每行的长度是否相同,每列的长度是否相同。如果二者分别相同,那么就是一个方形,也就是一个合法的船只。举例说明。
###
###
是合法的船只,第一行长度为3,第二行长度也为3;第一列长度为2,第二,三列长度也为2。故合法,是一个船只。
....#.
....#.
....#.
....##
可以看到行上的’#'数并不完全相同,列上的‘#’也不相同,故不合法。
我们用一个行列数组,标记在深搜访问时得到的船只位置,然后在check()
函数中判断是否合法,返回true
,false
就行。
3.代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxR = 1005;
char map[maxR][maxR];//地图
int row[maxR],col[maxR];//行列分别有多少船只
int vis[maxR][maxR];//访问信息
int R,C,ans;
int dx[4] = {-1,1,0,0}, dy[4]={0,0,-1,1};
//检查坐标(x,y)点所在的船只的行列信息
bool check(){
int i,j, iV,jV;//行列遍历; i value; j Value
for(i = 0;i<R;i++){
if(row[i]!=0){
iV = row[i];
break;
}
}
for(;i<R;i++) {
if(row[i]!=iV && row[i]!=0)
return false;
}
for(j = 0;j<C;j++){
if(col[j]!=0){
jV = col[j];
break;
}
}
for(;j<C;j++) {
if(col[j]!=jV && col[j]!=0)
return false;
}
return true;
}
//(cx,cy)为当前的判断坐标
void dfs(int cx,int cy){
//往上下左右四个方向遍历
int tx,ty;
for(int i = 0;i<4;i++){
tx = cx+dx[i], ty = cy+dy[i];
if(tx >=0 && tx<R && ty>=0 && ty <C
&& vis[tx][ty] == 0 && map[tx][ty]=='#'){//在边界内
vis[tx][ty] = 1;
row[tx]++, col[ty]++;
dfs(tx,ty);
}
}
}
int main(){
cin >> R >> C;
for(int i = 0;i< R;i++){
for(int j = 0;j<C;j++){
cin >> map[i][j];
}
}
fill(vis[0],vis[0]+maxR*maxR,0);
for(int i = 0;i< R;i++){
for(int j = 0;j<C;j++){
if(vis[i][j]==0 && map[i][j] == '#'){//
memset(row,0,sizeof(row));
memset(col,0,sizeof(col));
ans++;
// cout << i<<","<<j<<"---\n";
// cout << ans<<"----\n";
dfs(i,j);
if(!check()){//如果不满足要求
cout<< "Bad placement.\n" ;
return 0;
}
}
}
}
cout << "There are "<<ans <<" ships.\n";
return 0;
}
4.测试用例
6 8
.....#.#
##.....#
##.....#
.......#
#......#
#..#..##
4 8
.....#.#
##.....#
##.....#
#......#
5 8
.....#.#
##.....#
##.....#
.......#
#......#
6 8
.....#.#
##.....#
##.....#
.......#
#......#
#..#...#