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
画图我们可以知道,我们要想经过所有的特殊点,只需要讨论两种情况,
一种是,B线上没有,那么只在A上走,
一种是B线上 有,那么我们只需要找到A的最左端,B的最左端、A的最右端、B的最右段的转折点即可,这样就可以保证走了一圈,肯定将所有的特殊点都经过了,并且路径最短
我们要特殊考虑一下如果只在起点S的左端有需要经过的点或者只在起点S右端怎么办呢
我们画图可以知道
他是这样走的,所以我们需要计算出
①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; }