狼和羊

51 篇文章 1 订阅
25 篇文章 1 订阅

题目:

Description
米基家的后院养着一群羊,米基由于疲劳睡着了,这时一群饿狼钻进了后院开始攻击羊群,后院是由许多个方格构
成的长方形区域,每个方格中用字符‘?’表示空地,‘#’表示栅栏,‘o’表示羊,‘v’表示狼,羊和狼所在的
格子都是空地。如果从一个空地A沿着水平方向或垂直方向经过一系列的空地能够到达空地B,则称空地A和空地B属
于同一个羊圈。对于能够逃离后院的空地我们认为它不属于任何一个羊圈。当一个羊圈中羊的数量大于狼的数量时
,它们会用它们的尖角顶死该羊圈中的狼,否则就将被狼吃掉,最后每个羊圈中只会剩下一种动物。写一个程序统
计战斗结束后所有羊圈中羊的总数和狼的总数。
Input
第一行包含两个用空格隔开的自然数R和C,其中3<=R,C<=250,R表示米基家后院的行数,C表示列数,接下来的R行
每行包含C个字符,每个字符表示一个格子的情况。
Output
仅一包含两个用一个空格隔开的整数,表示要求的羊的数量和狼的数量。
Sample Input

9 12
.###.#####…
#.oo#…#v#.
#…o#.#.#.#.
#…##o#…#.
#.#v#o###.#.
#…#v#…#.
#…v#v####.
.####.#vv.o#
…####.

Sample Output

3 5


广搜入门,比较简单,相当于找联通块加强版,for循环遍历所有点,BFS它,把每个联通块中算出来的羊数量和狼数量比较一下即可。

代码:

#include <bits/stdc++.h>
using namespace std;

int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int tmp1,tmp2,n,m,ans1,ans2,vis[1010][1010];

char mp[1010][1010];

bool in(int x,int y){
	return x>=1&&x<=n&&y>=1&&y<=m;
}

struct node{
	int x,y;
	
	node(int xx,int yy){
		x=xx;
		y=yy;
		
	}
	
};

void bfs(int sx,int sy){
	queue<node> q;
	q.push(node(sx,sy));
	
	while (!q.empty()){
		node now=q.front();
		q.pop();
		
		for (int i=0;i<4;i++){
			int tx=now.x+dir[i][0];
			int ty=now.y+dir[i][1];
			
			if(mp[tx][ty]=='#'||vis[tx][ty]||!in(tx,ty)){
				continue;
			}
			vis[tx][ty]=1;
			if(mp[tx][ty]=='.'){
				q.push(node(tx,ty));
			}
			if(mp[tx][ty]=='v'){
				q.push(node(tx,ty));
				tmp1++;
				
			}
			if(mp[tx][ty]=='o'){
				q.push(node(tx,ty));
				tmp2++;
			}
		}
		
	}
	
}

int main(){
	cin>>n>>m;
	
	for (int i=1;i<=n;i++){
		for (int j=1;j<=m;j++){
			cin>>mp[i][j];
		}
	}
	
	for (int i=1;i<=n;i++){
		for (int j=1;j<=m;j++){
			tmp1=0;
			tmp2=0;//tmp1表示这个羊圈的狼数量,tmp2表示羊数量
			if(!vis[i][j]){
				bfs(i,j);
			}
			if(tmp1>=tmp2){
				ans2+=tmp1;
			}else {
				ans1+=tmp2;
			}
		}
	}
	cout<<ans1<<" "<<ans2;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值