solve:4/11
补题:6/11
补题:zz
这是一道分类讨论的题目,有一个规律就是如果必须要从第一个区到第二个区,那么最多转区两次(1到2一次,2到1一次),然后分类讨论即可,只要细心一定能做出来。
//#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<string> #include<math.h> #include<cmath> #include<time.h> #include<map> #include<set> #include<vector> #include<queue> #include<algorithm> #include<numeric> #include<stack> #include<bitset> #include<unordered_map> const int maxn = 0x3f3f3f3f; const double EI = 2.71828182845904523536028747135266249775724709369995957496696762772407663035354594571382178525166427; const double PI = 3.141592653589793238462643383279; //#ifdef TRUETRUE //#define gets gets_s //#endif using namespace std; int c[2][1000010]; int z[2][100010], cnt[5]; int d[111]; int main(void) { //ios::sync_with_stdio(false); int n, rr, k, m, s, i, x, y, l1, l2, r1, r2, ans, l, r, j; while (~scanf("%d %d %d %d %d", &n, &rr, &m, &k, &s)) { memset(c, 0, sizeof(c)); cnt[0] = 0; cnt[1] = 0; for (i = 0; i < rr; i++) { scanf("%d %d", &x, &y); if (x == s && y == 0) { continue; } c[y][x] = 1; z[y][cnt[y]++] = x; } for (i = 0; i < m; i++) { scanf("%d", d + i); } sort(z[0], z[0] + cnt[0]); sort(z[1], z[1] + cnt[1]); l1 = -1; l2 = -1; r1 = -1; r2 = -1; if (cnt[0]) { l1 = z[0][0]; r1 = z[0][cnt[0] - 1]; } if (cnt[1]) { l2 = z[1][0]; r2 = z[1][cnt[1] - 1]; } ans = 0; if (l2 != -1) { ans += k * 2; } l = min(l1, l2); if (l1 == -1) { l = l2; } else if (l2 == -1) { l = l1; } r = max(r1, r2); d[m++] = 1; d[m++] = n; d[m++] = n + 1; sort(d, d + m); /*for (i = 0;i < m;i++) { printf("%d ", d[i]); } printf("\n");*/ //printf("l = %d r = %d\n", l, r); if (r <= s && r != -1 && l != -1) { //printf("l = %d r = %d\n",l,r); for (i = 0; i < m; i++) { if (d[i] <= l && d[i + 1] > l) { break; } } ans += s - d[i]; //printf("ans = %d\n",ans); if (l2 != -1) { for (j = 0; j < m; j++) { if (d[j] >= r2) { break; } } ans += d[j] - d[i]; ans += abs(s - d[j]); } else { ans += s - d[i]; } } else if (l >= s && r != -1 && l != -1) { for (i = 0; i < m; i++) { if (d[i] >= r) { break; } } ans += d[i] - s; if (l2 != -1) { for (j = m - 1; j >= 0; j--) { if (d[j] <= l2) { break; } } ans += d[i] - d[j]; ans += abs(s - d[j]); } else { ans += d[i] - s; } } else if (l <= s && r >= s && r != -1 && l != -1) { for (i = 0; i < m; i++) { if (d[i] <= l && d[i + 1] > l) { break; } } //printf(" %d\n",ans); ans += 2 * (s - d[i]); //printf(" %d %d %d %d %d\n", ans,d[i],i,l,r); for (i = 0; i < m; i++) { if (d[i] <= r && d[i + 1] >= r) { break; } } ans += 2 * (d[i + 1] - s); //printf(" %d %d\n", ans,d[i + 1]); } printf("%d\n", ans); } return 0; }