络谷 P1331 海战

络谷 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()函数中判断是否合法,返回truefalse就行。

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
.....#.#
##.....#
##.....#
.......#
#......#
#..#...#
发布了954 篇原创文章 · 获赞 307 · 访问量 112万+

猜你喜欢

转载自blog.csdn.net/liu16659/article/details/104648021