• CCPC-Wannafly Winter Camp Day4 Div1


    题目链接:https://zhixincode.com/contest/18/problem/A?problem_id=259

    题目描述

    wls正在玩一个寻宝游戏。

    宝藏一共有 $n$ 种,都藏在一个 $m$ 行 $m$ 列的网格中。

    每种宝藏都恰好有两个。

    wls只能沿着网格走(上下左右四个方向)。

    他想依次获得 $1...n$ 类宝藏,然后再以 $n...1$ 的顺序获得剩下的宝藏。

    wls可以从任意点出发。

    当wls到达某个宝藏的位置时,他可以选择取或不取这个宝藏。

    请问他最少要移动多少距离?

    输入描述

    第一行两个整数 $n$,$m$。

    接下来 $n$ 组,每组两行表示一类宝藏,每行两个整数 $x$,$y$ 表示一个宝藏的坐标。

    $1≤n,m≤100000$
    $1≤x,y≤m$

    输出描述

    一行一个整数表示答案。

    题解:

    将问题转换为两个人同时从第 $1$ 种宝藏出发,沿着 $1~n$ 的顺序拿宝藏。

    假设第 $1$ 种宝藏分别为 $1a$ 和 $1b$,第 $2$ 种宝藏也分别为 $2a,2b$,那么只有两种选择 $1a → 2a, 1b → 2b$ 或者 $1a → 2b, 1b → 2a$,选择路程更短的就好了,因为不管当前怎么选择,对之后都没有任何影响。

    最后再加个 $na$ 到 $nb$ 之间的路程就好了。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    int n,m;
    struct P{
        int x,y;
    }p[maxn][2];
    ll dist(P a,P b)
    {
        return (ll)abs(a.x-b.x)+abs(a.y-b.y);
    }
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&p[i][0].x,&p[i][0].y);
            scanf("%d%d",&p[i][1].x,&p[i][1].y);
        }
    
        ll ans=0;
        for(int i=2;i<=n;i++)
        {
            ans+=min(dist(p[i-1][0],p[i][0])+dist(p[i-1][1],p[i][1]),dist(p[i-1][0],p[i][1])+dist(p[i-1][1],p[i][0]));
        }
        cout<<ans+dist(p[n][0],p[n][1])<<endl;
    }
  • 相关阅读:
    计数排序
    epel
    Web开发:我希望得到的编程学习路线图
    第五章:if语句与运算符
    java web学习建议
    第四章:c++数据类型
    第二章:做一个最简单的c++程序
    linux的商业应用
    第三章:初步了解函数
    解析Linux商业应用现状
  • 原文地址:https://www.cnblogs.com/dilthey/p/10383355.html
Copyright © 2020-2023  润新知