解题思路
链接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);
}