在坐标\((x,y)\)上
若\(x+y\)是偶数则可以走向\((x+1,y)\)
若\(x+y\)是奇数则可以走向\((x+1,y+1)\)
但是你可以使用一个花费,使得他能走的点和不能走的点反过来
你起点在\((1,1)\),给你\(n(n\leq 2\times 10^5)\)个点,求最少使用多少个花费,使得能到达所有点
保证一定可以到达所有点
既然一定能到达所有点,那么显然到达的先后顺序一定是按照\(x\)坐标升序进行的
所以只要确定两个点之间的花费即可
若要从在\((x1,y1)\)走到\((x2,y2)\)
设\(pos=y1+x2-x1-1\) 若\(y2=pos+1\) 那么显然每一步都是只能往右走,答案就是\(x2-x1\)
否则那么还要往左多走\(y2-pos\)步,答案显然为\(\frac{y2-pos+1}{2}\)
设\(pos=y1+x2-x1 \;\) \(pos\)显然不大于\(y2\)
否则那么还要往左多走\(y2-pos\)步,答案显然为\(\frac{y2-pos+1}{2}\)
#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=2e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-6;
typedef pair<int,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
int n;
pii pa[maxn];
int cal(int x1,int y1,int x2,int y2){
if(x1==x2) return 0;
int ans;
if((x1+y1)%2==1){
int pos=y1+x2-x1;
int dif=pos-y2;
ans=(dif+1)/2;
}else{
int pos=y1+x2-x1-1;
if(pos<y2){
ans=x2-x1;
}else{
int dif=pos-y2;
ans=(dif+1)/2;
}
}
return ans;
}
signed main(){
int _;scanf("%d",&_);
while(_--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&pa[i].fi);
}
for(int i=1;i<=n;i++){
scanf("%d",&pa[i].se);
}
sort(pa+1,pa+1+n);
pa[0].fi=pa[0].se=1;
int ans=0;
for(int i=0;i<=n-1;i++){
ans+=cal(pa[i].fi,pa[i].se,pa[i+1].fi,pa[i+1].se);
}
printf("%d\n",ans);
}
return 0;
}
原文:https://www.cnblogs.com/hunxuewangzi/p/14586207.html