海战(洛谷 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.
/* 一道搜索题,加上一点判断,判断所找到的连通块是不是长方形 判断的方法:假设是长方形,找到四个顶点,算连通块的面积是不是等于点的个数 */ 代码: #include<cstdio> #include<iostream> #include<algorithm> #define M 1010 using namespace std; bool vis[M][M]; int map[M][M],qx[M*M],qy[M*M],n,m,cnt; int ax[4]={0,0,1,-1}; int ay[4]={1,-1,0,0}; struct node { int x,y; };node ship[M*M]; int read() { char c=getchar();int num=0,flag=1; while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*flag; } void bfs(int a,int b) { int head=0,tail=1; qx[1]=a;qy[1]=b; vis[a][b]=true; while(head<tail) { int x=qx[++head],y=qy[head]; ship[++cnt].x=x;ship[cnt].y=y; for(int i=0;i<4;i++) { int xx=x+ax[i]; int yy=y+ay[i]; if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&!vis[xx][yy]&&map[xx][yy]) { qx[++tail]=xx; qy[tail]=yy; vis[xx][yy]=true; } } } } int cmp(const node&aa,const node&bb) { if(aa.x<bb.x)return 1; if(aa.x==bb.x&&aa.y<bb.y)return 1; return 0; } bool check() { sort(ship+1,ship+cnt+1,cmp); int x2=0,y2=0,x3=0,y3=0; int x1=ship[1].x,y1=ship[1].y; int x4=ship[cnt].x,y4=ship[cnt].y; for(int i=1;i<=cnt;i++) { if(ship[i].x==x1&&ship[i].y==y4) x2=ship[i].x,y2=ship[i].y; if(ship[i].x==x4&&ship[i].y==y1) x3=ship[i].x,y3=ship[i].y; } if((!x2)||(!x3))return false; if((x4-x1+1)*(y4-y1+1)!=cnt)return false; return true; } int main() { n=read();m=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { char c;cin>>c; if(c=='#')map[i][j]=1; else map[i][j]=0; } int tot=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(map[i][j]&&!vis[i][j]) { tot++; cnt=0; bfs(i,j); if(!check()) { printf("Bad placement."); return 0; } } printf("There are %d ships.",tot); return 0; }