F Triangular Paths 题解(思维)

题目链接

题目大意

在坐标((x,y))

  • (x+y)是偶数则可以走向((x+1,y))

  • (x+y)是奇数则可以走向((x+1,y+1))

但是你可以使用一个花费,使得他能走的点和不能走的点反过来

你起点在((1,1)),给你(n(nleq 2 imes 10^5))个点,求最少使用多少个花费,使得能到达所有点

保证一定可以到达所有点

题目思路

既然一定能到达所有点,那么显然到达的先后顺序一定是按照(x)坐标升序进行的

所以只要确定两个点之间的花费即可

若要从在((x1,y1))走到((x2,y2))

  • (x1+y1)是偶数,总共走(x2-x1)步不考虑花费的情况,显然为((x2,y1+x2-x1-1))

(pos=y1+x2-x1-1)(y2=pos+1) 那么显然每一步都是只能往右走,答案就是(x2-x1)

否则那么还要往左多走(y2-pos)步,答案显然为(frac{y2-pos+1}{2})

  • (x1+y1)是奇数,总共走(x2-x1)步不考虑花费的情况,显然为((x2,y1+x2-x1))

(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
",ans);
    }
    return 0;
}

卷也卷不过,躺又躺不平
原文地址:https://www.cnblogs.com/hunxuewangzi/p/14586207.html