您的位置:首页 > 其它

pku2110求一点至另一点的路径中高度差最小的值

2011-07-24 11:09 302 查看
现在有一个N*N的矩阵,每个位置是一个整数,代表这点的高度,站在某个位置上的人,只能向上下左右四个方向移动,求从(1,1)至(N,N)间的所有路径中高度差最小的值。N<=100 height<=110
开始想直接借用最短路的思想做,但发现是错误的。还是用一般的想法吧,二分高度差+枚举最小高度。。。确定了这两个,高度的范围就确定了,那么可以直接广搜,但能不能从(1,1)至(N,N)。如果某个高度差可以找到一个最小高度,那么就将高度差减小,否则增加。
#include<iostream>
using namespace std;

int n,g[110][110],q[11000];
bool inq[11000];
int next[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
bool IN(int now,int s,int len)
{
if(now>=s&&now<=s+len) return true;
return false;
}
bool IsIN(int x,int y)
{
if(x<0||x>=n) return false;
if(y<0||y>=n) return false;
return true;
}
bool OK(int s,int len)
{
int head=0,tail=0,i,j,k,ii,jj;
memset(inq,false,sizeof(inq));
if(IN(g[0][0],s,len))
{
inq[0]=true;
q[tail++]=0;
}
while(head!=tail)
{
k=q[head++];
i=k/n,j=k%n;
for(k=0;k<4;k++)
{
ii=i+next[k][0];
jj=j+next[k][1];
if(IsIN(ii,jj)&&!inq[ii*n+jj]&&IN(g[ii][jj],s,len))
{
inq[ii*n+jj]=true;
q[tail++]=ii*n+jj;
}
}
}
if(inq[n*n-1]) return true;
return false;
}
int main()
{
int i,j,s,l,r,mid;
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&g[i][j]);
l=0,r=111;
while(l<=r)
{
mid=(l+r)/2;
for(s=0;s+mid<=110;s++)
{
if(OK(s,mid))
break;
}
if(s+mid<=110)
{
i=mid;
r=mid-1;
}
else l=mid+1;
}
printf("%d\n",i);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: