luogu P1331 海战
P1331 海战
题目描述
在峰会期间,武装部队得处于高度戒备。警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞机。此外,巡洋船只和舰队将被派去保护海岸线。不幸的是因为种种原因,国防海军部仅有很少的几位军官能指挥大型海战。因此,他们考虑培养一些新的海军指挥官,他们选择了“海战”游戏来帮助学习。
在这个著名的游戏中,在一个方形的盘上放置了固定数量和形状的船只,每只船却不能碰到其它的船。在这个题中,我们仅考虑船是方形的,所有的船只都是由图形组成的方形。编写程序求出该棋盘上放置的船只的总数。
输入输出格式
输入格式:输入文件头一行由用空格隔开的两个整数R和C组成,1<=R,C<=1000,这两个数分别表示游戏棋盘的行数和列数。接下来的R行每行包含C个字符,每个字符可以为“#”,也可为“.”,“#”表示船只的一部分,“.”表示水。
输出格式:为每一个段落输出一行解。如果船的位置放得正确(即棋盘上只存在相互之间不能接触的方形,如果两个“#”号上下相邻或左右相邻却分属两艘不同的船只,则称这两艘船相互接触了)。就输出一段话“There are S ships.”,S表示船只的数量。否则输出“Bad placement.”。
输入输出样例
输入样例#1:
6 8 .....#.# ##.....# ##.....# .......# #......# #..#...#
输出样例#1:
There are 5 ships.
/* 这道题和单纯的dfs搜块数的差别在于,如果两个非矩阵连接则判定非法。 如果知道判断方法,这道题就变得简单了。 思路如下 用x1,y1记下起始点,x2,y2记下搜索最远的点,s记下搜索的步数(面积); 若(x2-x1+1)*(y2-y1+1)!=s 则为非法;666 下面是代码 */ #include<iostream> #include<cstdio> using namespace std; int a[1001][1001]; int r,c; int x1,y1,x2,y2,s=0,ans=0; int dfs(int x,int y) { if(x<x1||y<y1) { s=-1; //因为是从上向下,从左向右搜索,所以如果左面或者上面有没搜到的一定是错误 return 0; } a[x][y]=0; s++; if(x>x2)x2=x; if(y>y2)y2=y; if(x-1>=1&&a[x-1][y]==1)dfs(x-1,y); if(y-1>=1&&a[x][y-1]==1)dfs(x,y-1); if(x+1<=r&&a[x+1][y]==1)dfs(x+1,y); if(y+1<=c&&a[x][y+1]==1)dfs(x,y+1); } int main() { int pd=0; cin>>r>>c; char ship; for(int i=1;i<=r;i++) { for(int j=1;j<=c;j++) { cin>>ship; if(ship=='#')a[i][j]=1; else a[i][j]=0; } } for(int i=1;i<=r;i++) { if(pd==1)break; for(int j=1;j<=c;j++) { if(a[i][j]==1) { x1=i; y1=j; x2=i; y2=j; dfs(i,j); if(s!=(x2-x1+1)*(y2-y1+1)||s==-1) { printf("Bad placement."); return 0; } s=0; ans++; } } } if(pd==0) printf("There are %d ships.",ans); return 0; }