hdu 3688 蛮巧的模拟

来源:互联网 发布:淘宝下架日是什么意思 编辑:程序博客网 时间:2024/05/16 10:35

没想出来,参考了网上的做法

枚举两个灯之间的最大距离,易知答案至少是这个距离的一半。

枚举每个灯,去掉不符合条件的灯,即level值小于当前ans的,这个时间是O(1)的,只是更改一下上下左右灯(如果有)的指向的灯

复杂度为输入的复杂度O(n*m)

View Code
#include<cstdio>
#include<cstring>
#include<ctype.h>
#include<algorithm>
using namespace std;
const int inf = 100000000;
const int maxn = 11111;
struct Light{
int x,y,level;
int next[4];
Light(){}
Light(int _x,int _y,int _level){
x=_x;
y=_y;
level=_level;
for(int i=0;i<4;i++)
next[i]=-1;
}
bool operator < (const Light &cmp) const{
return level<cmp.level;
}
void update();
};
int n,m,ans;
int a[110][maxn];
Light light[110*maxn];
void Light::update(){
int left=next[0];
int right=next[2];
if(left!=-1) light[left].next[2]=right;
if(right!=-1) light[right].next[0]=left;
if(left==-1 && right == -1) ans=inf;
else if(left==-1) ans=max(ans,light[right].y);
else if(right==-1) ans=max(ans,m-light[left].y+1);
else ans=max(ans,(light[right].y-light[left].y+2)/2);

int up=next[1];
int down=next[3];
if(up!=-1) light[up].next[3]=down;
if(right!=-1) light[down].next[1]=up;
if(up==-1&&down==-1) ans=inf;
else if(up==-1) ans=max(ans,light[down].x);
else if(down==-1) ans=max(ans,n-light[up].x+1);
else ans=max(ans,(light[down].x-light[up].x+2)/2);

}
int main(){
int i,j;
while(scanf("%d%d",&n,&m),(n||m)){
int tot=0;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%d",&a[i][j]);
if(a[i][j])
light[++tot]=Light(i,j,a[i][j]);
}
}
sort(light+1,light+tot+1);
for(i=1;i<=tot;i++)
a[light[i].x][light[i].y]=i;
ans=0;
int pre;
for(i=1;i<=n && ans!=inf ; i++){
pre=-1;
for(j=1;j<=m;j++){
if(a[i][j]){
if(pre==-1) ans=max(ans,j);
else {
ans=max(ans,j-pre+2)/2;
light[a[i][j]].next[0]=a[i][pre];
light[a[i][pre]].next[2]=a[i][j];
}
pre=j;
}
}
if(pre==-1) ans=inf;
else ans=max(ans,m-pre+1);
}
for(i=1;i<=m&&ans!=inf;i++){
pre=-1;
for(j=1;j<=n;j++){
if(a[j][i]){
if(pre==-1) ans=max(ans,j);
else {
ans=max(ans,(j-pre+2)/2);
light[a[j][i]].next[1]=a[pre][i];
light[a[pre][i]].next[3]=a[j][i];
}
pre=j;
}
}
if(pre==-1) ans=inf;
else ans=max(ans,n-pre+1);
}
int t=1;
while(ans<inf && t<=tot && light[t].level < ans)
light[t++].update();
if(ans==inf) puts("NO ANSWER!");
else printf("%d\n",ans);
}
return 0;
}