内容目录
显然除了直接移(先行后列)外,
唯一减少操作数的方法便是向中间以外的行数移,以求降低列的移动数。
一定要注意不是挪到每行直接取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; }