题目大意:
方阵的某些格子里有灯,且其能照明的范围不一,只能在四个方向上照明;灯的亮度可调,求能够使得该位置有灯亮或者该位置的横向和纵向均有灯照明的可行的最小亮度
我想说,,,这种方法一般人谁想得到啊,不参考网上的做法,我真是不知道可以这样做,,,刚开始还想着用二分灯光亮度来写嘞;;;;
枚举横纵方向上两个灯之间距离,当两边都有灯时为之间距离的一半加一,特别的在边界上的情况要单独考虑
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define inf 0x3f3f3f3f
using namespace std;
int n,m,mp[109][10009],ans;
struct node
{
int x,y,level,next[4];
node(int a=0,int b=0,int c=0):x(a),y(b),level(c)
{
memset(next,-1,sizeof next);
}
void update();
} vex[109*10009];
void node::update()//当灯的亮度小于当前结果时将其关闭,更新四个方向上的灯的状态
{
int left=next[0],right=next[2];
if(left!=-1) vex[left].next[2]=right;
if(right!=-1) vex[right].next[0]=left;
if(left==-1&&right==-1) ans=inf;//此行上没有灯
else if(left==-1) ans=max(ans,vex[right].y);//仅右边有灯
else if(right==-1) ans=max(ans,m-vex[left].y+1);
else ans=max(ans,(vex[right].y-vex[left].y+2)>>1);//两边都有灯时所需要的亮度为两灯之间距离的一半加一
int up=next[1],down=next[3];
if(up!=-1) vex[up].next[3]=down;
if(down!=-1) vex[down].next[1]=up;
if(up==-1&&down==-1) ans=inf;
else if(up==-1) ans=max(ans,vex[down].x);
else if(down==-1) ans=max(ans,n-vex[up].x+1);
else ans=max(ans,(vex[down].x-vex[up].x+2)>>1);
}
int cmp(node a,node b)
{
return a.level<b.level;
}
int main()
{
while(scanf("%d%d",&n,&m)&&(n||m))
{
int tot=0;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
scanf("%d",&mp[i][j]);
if(mp[i][j]) vex[++tot]=node(i,j,mp[i][j]);
}
sort(vex+1,vex+1+tot,cmp);
for(int i=1; i<=tot; i++) mp[vex[i].x][vex[i].y]=i;
ans=0;
for(int i=1; i<=n&&ans!=inf; i++)
{
int pre=-1;
for(int j=1; j<=m; j++)
{
if(mp[i][j])
{
if(pre==-1) ans=max(ans,j);
else
{
ans=max(ans,(j-pre+2)>>1);
vex[mp[i][j]].next[0]=mp[i][pre];
vex[mp[i][pre]].next[2]=mp[i][j];
}
pre=j;
}
}
if(pre==-1) ans=inf;
else
ans=max(ans,m-pre+1);//边界情况单独考虑
}
for(int i=1; i<=m&&ans!=inf; i++)
{
int pre=-1;
for(int j=1; j<=n; j++)
{
if(mp[j][i])
{
if(pre==-1) ans=max(ans,j);
else
{
ans=max(ans,(j-pre+2)>>1);
vex[mp[j][i]].next[1]=mp[pre][i];
vex[mp[pre][i]].next[3]=mp[j][i];
}
pre=j;
}
}
if(pre==-1) ans=inf;
else
ans=max(ans,n-pre+1);
}
int i=1;
while(i<=tot&&vex[i].level<ans&&ans<inf)
{
vex[i++].update();
}
if(ans==inf) puts("NO ANSWER!");
else printf("%d\n",ans);
}
}