https://codeforces.com/contest/1105/problem/D
题意:给n*m的地图,最多9个人,同时有每个人最多扩张si次(不是直线最大距离,被坑了)地图上有‘#’,‘.’,和数字,数字对应每个人的据点,从1-n轮流扩张。
地图被扩张完后,输入每个人的据点数目。
思路:用bfs,注意每次队列里储存的是该次bfs所能到达的点,把最远能达到的点,即到当前步数为0的点记录下来,下次再使用,如果没有能放入的点结束。
这次犯了个致命错误导致改了很久,就是bfs的vis标记应该在入队时标记,不然队列中会储存大量重复的点,导致MLE!!! 好久没用bfs ,犯这种错误
#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define fi first
#define se second
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
using namespace std;
typedef long long ll;
typedef pair<char, ll> P;
typedef pair<P, int> LP;
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 100;
const int mod = 1e9+7;
const int base=131;
tr1::unordered_map<ll,ll> mp;
inline ll mul(ll x,ll y) { return (x*y-(ll)((long double)x*y/mod)*mod+mod)%mod;}
inline ll ksm(ll a,ll b) {ll ans=1;while(b){if(b&1)ans=mul(ans,a);a=mul(a,a),b>>=1;}return ans;}
int gcd(int x, int y) {
return y?gcd(y,x%y):x;
}
ll n,m;
int num[1005][1005],vis[1005][1005],a[50];
int k,ans[N],cnt;
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int p;
char s[1005][1005];
int flag;
struct node
{
int x,y,w;
node(){};
node (int a,int b,int c)
{
x=a;y=b;w=c;
}
}no[N];
vector<node> q[20];
vector<node> v;
bool check(int x,int y,int w)
{
if(x<1||y<1||x>n||y>m){return 0;}
if(vis[x][y]) {return 0;}
if(s[x][y]!='.') return 0;
if(w<0) return 0;
return 1;
}
void bfs(int k)
{
queue<node> tq;
for(auto no:q[k])
{
tq.push(no);
}
q[k].clear();
while(tq.size())
{
node now=tq.front();tq.pop();
int x=now.x,y=now.y,w=now.w;
if(w==0) q[k].push_back(node(x,y,a[k]));
for(int i=0;i<4;i++)
{
int nx=x+dx[i];
int ny=y+dy[i];
if(check(nx,ny,w-1))
{
vis[nx][ny]=k;//致命错误 vis应该放在入队前面
tq.push(node{nx,ny,w-1});
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>p;
for(int i=1;i<=p;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++) cin>>s[i]+1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
if(isdigit(s[i][j]))
{
int id=(int)(s[i][j]-'0');
q[id].push_back(node(i,j,a[id]));
vis[i][j]=id;
}
}
while(1)
{
int flag=0;
for(int i=1;i<=p;i++)
{
if(!q[i].size()) continue;
bfs(i);
if(q[i].size()) flag=1;
}
if(!flag) break;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
ans[vis[i][j]]++;
}
}
for(int i=1;i<=p;i++) cout<<ans[i]<<" ";
}