您的位置:首页 > 其它

【Codeforces845E】Fire in the City

2017-09-27 09:49 330 查看
题意:

一个火源第i秒形成的火区是一个边长为2i+1的正方形

在n×m的网格中,问已知k个火源,再加一个之后(由你选),问最少的时间可以将所有区域变为火区。

首先最少时间肯定需要二分mid,然后每个火区的关键点就只有4个。离散化后可以二维差分一下算出最上、下、左、右的四个没有被烧到的关键点。看看和mid之间的关系就好了。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define mid (l+r>>1)
#define inf 0x3f3f3f3f
#define N 509
using namespace std;
int n,m,k,a
,b
;
vector<int> x,y;
vector<int> ::iterator it;
/*map<int,int> x,y;
map<int,int> ::iterator it;*/
int tg[N*2][N*2];
//int X[N*2],Y[N*2],number_x,number_y;
int read()
{
int x=1;
char ch;
while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
int s=ch-'0';
while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
return x*s;
}
bool check(int lim)
{
x.clear(),y.clear();
//number_x=number_y=0;
for (int i=1;i<=k;i++)
{
int Up=max(1,a[i]-lim),Down=min(n,a[i]+lim);
int Left=max(1,b[i]-lim),Right=min(m,b[i]+lim);
/*x[Up]=inf,x[Down+1]=inf;
y[Left]=inf,y[Right+1]=inf;*/
x.push_back(Up),x.push_back(Down+1);
y.push_back(Left),y.push_back(Right+1);
}
/*x[1]=x[n+1]=inf;
y[1]=y[m+1]=inf;
for (it=x.begin();it!=x.end();it++)
X[++number_x]=(*it).first,(*it).second=number_x;
for (it=y.begin();it!=y.end();it++)
Y[++number_y]=(*it).first,(*it).second=number_y;*/
x.push_back(1),x.push_back(n+1);
y.push_back(1),y.push_back(m+1);
sort(x.begin(),x.end());
sort(y.begin(),y.end());
x.erase(unique(x.begin(),x.end()),x.end());
y.erase(unique(y.begin(),y.end()),y.end());
memset(tg,0,sizeof(tg));
for (int i=1;i<=k;i++)
{
int Up=max(1,a[i]-lim),Down=min(n,a[i]+lim);
int Left=max(1,b[i]-lim),Right=min(m,b[i]+lim);
Up=lower_bound(x.begin(),x.end(),Up)-x.begin()+1;
Down=lower_bound(x.begin(),x.end(),Down+1)-x.begin()+1;
Left=lower_bound(y.begin(),y.end(),Left)-y.begin()+1;
Right=lower_bound(y.begin(),y.end(),Right+1)-y.begin()+1;
/*tg[x[Up]][y[Left]]++,tg[x[Up]][y[Right+1]]--;
tg[x[Down+1]][y[Left]]--,tg[x[Down+1]][y[Right+1]]++;*/
tg[Up][Left]++,tg[Up][Right]--;
tg[Down][Left]--,tg[Down][Right]++;
}
int Min_x=inf,Min_y=inf,Max_x=0,Max_y=0;
for (int i=1;i<(int)x.size();i++)
for (int j=1;j<(int)y.size();j++)
{
tg[i][j]+=tg[i][j-1]+tg[i-1][j]-tg[i-1][j-1];
if (!tg[i][j])
{
Min_x=min(Min_x,i),Max_x=max(Max_x,i);
Min_y=min(Min_y,j),Max_y=max(Max_y,j);
}
}
if (Min_x==inf) return 1;
Min_x=x[Min_x-1],Min_y=y[Min_y-1];
Max_x=x[Max_x]-1,Max_y=y[Max_y]-1;
return (Max_x-Min_x<=lim*2&&Max_y-Min_y<=lim*2);
}
int main()
{
n=read(),m=read(),k=read();
for (int i=1;i<=k;i++) a[i]=read(),b[i]=read();
int l=0,r=max(n,m)/2,ret=0;
while (l<=r)
{
if (check(mid)) ret=mid,r=mid-1;
else l=mid+1;
}
printf("%d\n",ret);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: