【洛谷 P7151 】 Replication G【BFS】

17 篇文章 0 订阅

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


解题思路

链接P7151 [USACO20DEC] Replication G 题解


代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<set>
#define ll long long
#define ldb long double
using namespace std;

const int dx[5]= {0,1,-1,0,0},dy[5]= {0,0,0,1,-1};
int n,d,h1,t1,h2,t2,sum,a[1100][1100],sh[1100][1100],dis[1100][1100],v[1100][1100];
struct c {
	int x,y,num;
} shi[1100000],ji[1100000];
char s;

struct lyx {
	int x,y,di;
	friend bool operator <(const lyx &s1,const lyx &s2) {
		return s1.di<s2.di;
	}
};
priority_queue<lyx> q;

int main() {
	memset(dis,-1,sizeof(dis));
	memset(sh,-1,sizeof(sh));
	scanf("%d%d",&n,&d);
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=n; j++) {
			cin>>s;
			if(s=='#') {
				a[i][j]=1;
				t1++;
				shi[t1].x=i,shi[t1].y=j,shi[t1].num=0;
				sh[i][j]=0;
			}
			if(s=='S') {
				a[i][j]=1;
				t2++;
				ji[t2].x=i,ji[t2].y=j,ji[t2].num=0;
				dis[i][j]=0;
			}
		}
	}
	h1=1, t1++;
	while(h1<t1) {
		int nn=shi[h1].num+1;
		for(int i=1; i<=4; i++) {
			int x=shi[h1].x+dx[i],y=shi[h1].y+dy[i];
			if(x>1&&y>1&&x<=n&&y<=n&&sh[x][y]<0) {
				shi[t1].x=x,shi[t1].y=y,shi[t1].num=nn;
				sh[x][y]=nn;
				++t1;
			}
		}
		h1++;
	}
	h2=1, t2++;
	while(h2<t2) {
		if(ji[h2].num/d>=sh[ji[h2].x][ji[h2].y]) {
			h2++;
			continue;
		}
		int nn=ji[h2].num+1;
		for(int i=1; i<=4; i++) {
			int x=ji[h2].x+dx[i],y=ji[h2].y+dy[i];
			if((nn-1)/d<sh[x][y]&&!a[x][y]&&dis[x][y]<0) {
				ji[t2].x=x,ji[t2].y=y,ji[t2].num=nn;
				dis[x][y]=nn;
				++t2;
			}
		}
		h2++;
	}
	lyx t,top;
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=n; j++) {
			if(dis[i][j]>=0) {
				t.x=i,t.y=j,t.di=min(sh[i][j]-1,dis[i][j]/d);
				q.push(t);
				v[i][j]=1;
				sum++;

			}
		}
	}
	while(!q.empty()) {
		top=q.top();
		q.pop();
		if(!top.di)
			continue;
		int nn=top.di-1;
		for(int i=1; i<=4; i++) {
			int x=top.x+dx[i],y=top.y+dy[i];
			if(!v[x][y]&&!a[x][y]) {
				v[x][y]=1;
				t.x=x,t.y=y,t.di=nn;
				q.push(t);
				sum++;
			}
		}
	}
	printf("%d",sum);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值