A:机器人

传送门:https://www.zhixincode.com/contest/1/problem/A

题意:地图是由A、B两根线组成的,机器人一开始是在A线上的S点,他初始时可以选择任意方向前进,但是除非碰见特殊点,否则是不能转弯的,他有r个必须经过的点分布在A线和B线上,有m个特殊点可以进行转向,这些特殊点对称分布在A、B两条线上,并且1,n这两个点也是特殊点,也就是说机器人一定可以转弯,A、B之间的距离是K,求机器人经过所有的必须经过的点后回到起点。

题解:画图.jpg

CCPC-Winter Camp div2 day1

CCPC-Winter Camp div2 day1

 

CCPC-Winter Camp div2 day1

画图我们可以知道,我们要想经过所有的特殊点,只需要讨论两种情况,

一种是,B线上没有,那么只在A上走,

一种是B线上 有,那么我们只需要找到A的最左端,B的最左端、A的最右端、B的最右段的转折点即可,这样就可以保证走了一圈,肯定将所有的特殊点都经过了,并且路径最短

我们要特殊考虑一下如果只在起点S的左端有需要经过的点或者只在起点S右端怎么办呢

我们画图可以知道CCPC-Winter Camp div2 day1

他是这样走的,所以我们需要计算出

①A、B的区间长lena,lenb

②A、B的区间长之差len2

这样就可以求出只在一边的情况

实际上,如果不在一边的话,A、B的区间长之差是0,所以这些都是可以分在同一种情况的,只需要对(0,len2)取一个max即可

代码如下:

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;

#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("input.txt","r",stdin);
#define IO ios::sync_with_stdio(false),cin.tie(0)

const double eps = 1e-8;
const int mod = 1000000007;
const int maxn = 2e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int a[maxn], b[maxn];
int flag = 0;
vector<int> p;
int n, r, m, k, s;
int main() {
#ifndef ONLINE_JUDGE
    FIN
#endif
    scanf("%d%d%d%d%d", &n, &r, &m, &k, &s);
    int tot1 = 0, tot2 = 0;
    for(int i = 0; i < r; i++) {
        int x, tmp;
        scanf("%d%d", &x, &tmp);
        if(tmp == 0) {
            a[tot1++] = x;
        } else {
            b[tot2++] = x;
        }
    }
    for(int i = 0; i < m; i++) {
        int x;
        scanf("%d", &x);
        p.push_back(x);
    }
    p.push_back(1);
    p.push_back(n);
    sort(a, a + tot1); sort(b, b + tot2);
    sort(p.begin(), p.end());
    int al = n, ar = 1, bl = n, br = 1;
    for(int i = 0; i < tot2; i++) {
        bl = min(bl, *(upper_bound(p.begin(), p.end(), b[i] ) - 1));
        br = max(br, *lower_bound(p.begin(), p.end(), b[i]));
    }
    p.push_back(s);
    sort(p.begin(), p.end());
    for(int i = 0; i < tot1; i++) {
        al = min(al, *(upper_bound(p.begin(), p.end(), a[i] ) - 1));
        ar = max(ar, *lower_bound(p.begin(), p.end(), a[i]));
    }
    al = min(al, bl), ar = max(ar, br);
    //cout<<al<<" "<<ar<<endl;

    if(tot2 == 0) {
        // cout << (ar - al) * 2 << endl;
        //防止只在一边的情况
        cout << (max(0, al - s) + max(0, s - ar) + ar - al) * 2 << endl; //s到a+a区间长*2
    } else {
        //防止只在一边的情况
        cout << (max(0, al - s) + max(0, s - ar)) * 2 + //s到a
             ar - al + br - bl + //ab区间长
             bl - al + ar - br + //a超出b
             k * 2 << endl; //跨越

    }
    return 0;
}
View Code

相关文章: