显然除了直接移(先行后列)外,
唯一减少操作数的方法便是向中间以外的行数移,以求降低列的移动数。
一定要注意不是挪到每行直接取abs(行尾-c2)的,因为可能会有往返行尾的路上有更小的,直接取行尾可能拉近它和c2的距离,但是这种操作是不可行的。
#include<cstdio>
#include<functional>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
#define MAXN (10000+100)
int a[MAXN],n;
int abs2(int a,int b)
{
if (a<b) return b-a;
else return a-b;
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
int r1,c1,r2,c2;
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
int mi=c1,ans=0,tans=1000000000;
if (r1<r2)
{
ans=r2-r1;
for (int i=r1+1;i<=r2;i++) mi=min(mi,a[i]+1);
tans=min(tans,ans+abs(mi-c2));
for (int i=r1-1,cost=2,mii=mi;i>=1;i--,cost+=2)
{
mii=min(mii,a[i]+1);
tans=min(tans,ans+cost+abs(mii-c2));
}
for (int i=r2+1,cost=2,mii=mi;i<=n;i++,cost+=2)
{
mii=min(mii,a[i]+1);
tans=min(tans,ans+cost+abs(mii-c2));
}
}
else
{
ans=r1-r2;
for (int i=r1-1;i>=r2;i--) mi=min(mi,a[i]+1);
tans=min(tans,ans+abs(mi-c2));
for (int i=r2-1,cost=2,mii=mi;i>=1;i--,cost+=2)
{
mii=min(mii,a[i]+1);
tans=min(tans,ans+cost+abs(mii-c2));
}
for (int i=r1+1,cost=2,mii=mi;i<=n;i++,cost+=2)
{
mii=min(mii,a[i]+1);
tans=min(tans,ans+cost+abs(mii-c2));
}
}
cout<<tans<<endl;
return 0;
}