zoukankan      html  css  js  c++  java
  • 牛客 codejan与旅行(枚举+贪心)

    这道题首先可以想到可以是一直走到某地,或者在某两个地方徘徊。

    首先我们要想到当前点第一次肯定要走到左边或者右边的第一个点,这是第一步。

    其次,在这个基础上,我们枚举所有的边,当作徘徊的边,这样就遍历了所有情况,另外,当距离长度为m的时候,我们正好顺手做了直达的情况。

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=1e6+10;
    const int mod=1e9+7;
    typedef long long ll;
    int pos[N];
    signed main(){
        int t;
        cin>>t;
        while(t--){
            int n,m,p;
            cin>>n>>m>>p;
            int i;
            int x=0;
            for(i=1;i<=n;i++){
                scanf("%lld",&pos[i]);
                if(pos[i]<p)
                    x=i;
            }
            ll ans=1e18;
            for(i=1;i<n;i++){
                if(i<=x){
                    if(x-i+1>m)
                        continue;
                    int tmp=m-(x-i+1);//徘徊的次数
                    int dis=p-pos[i];//到某点的长度
                    ans=min(ans,dis+tmp*(pos[i+1]-pos[i]));
                    if(tmp&&x+i<=n){//如果可以走到当前点的右边
                        ans=min(ans,dis+2*(pos[x+1]-p)+(tmp-1)*(pos[i+1]-pos[i]));
                    }
                }
                else{
                    if(i-x>m)
                        continue;
                    int tmp=m-(i-x);//当剩下一次的时候,就是走到了终点n
                    int dis=pos[i]-p;
                    ans=min(ans,dis+tmp*(pos[i+1]-pos[i]));
                    if(tmp&&x>=1){
                        ans=min(ans,dis+2*(p-pos[x])+(tmp-1)*(pos[i+1]-pos[i]));
                    }
                }
            }
            cout<<ans<<endl;
        }
    }
    View Code
  • 相关阅读:
    JZOJ 3845. 简单题(simple)
    JZOJ 3844. 统计损失(count)
    JZOJ 3843. 寻找羔羊(agnus)
    JZOJ 3833. 平坦的折线
    JZOJ 1956. 矩形
    JZOJ 3832. 在哪里建酿酒厂
    mysql 语法一 :case when详解
    阿里云推荐码
    redis配置文件详解(转)
    压力测试工具 webbench总结
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12918446.html
Copyright © 2011-2022 走看看