[关闭]
@dxbdly 2021-02-08T11:14:09.000000Z 字数 3300 阅读 164

C2020 2020.12.19模拟赛

信息学——模拟赛


T1 Piggyback

分析

考虑如果没有背着走的情况。

答案显然就是号点到号点的最短路。

考虑最后背着走的路径,一定是某个点到号点的最短路。

考虑枚举相遇的点,那么答案为

分别求出三条最短路,取min即可。

  1. //The code is from dawn_sdy
  2. #include<bits/stdc++.h>
  3. #define INF INT_MAX
  4. #define int long long
  5. using namespace std;
  6. inline int read() {
  7. int x = 0;
  8. char c = getchar();
  9. bool f = 0;
  10. while(!isdigit(c)) f |= (c == '-'), c = getchar();
  11. while(isdigit(c)) x = (x * 10) + (c ^ 48), c = getchar();
  12. return f ? -x : x;
  13. }
  14. const int maxn = 4 * 1e4 + 5;
  15. int b, e, p, n, m;
  16. struct node {
  17. int v, nex;
  18. }edge[maxn << 1];
  19. int head[maxn], len;
  20. int dist[maxn], vst[maxn], dist1[maxn], dist2[maxn], distn[maxn], ans = INF;
  21. inline void make_map(int u, int v) {
  22. len++;
  23. edge[len].nex = head[u];
  24. edge[len].v = v;
  25. head[u] = len;
  26. }
  27. inline void Dijstra(int st) {
  28. #define pi pair<int,int>
  29. #define mp make_pair
  30. memset(vst, 0, sizeof(vst));
  31. for(register int i = 1; i <= n; ++i) dist[i] = INF;
  32. priority_queue < pi > q;
  33. q.push(mp(0, st)), vst[st] = dist[st] = 0;
  34. while(!q.empty()) {
  35. int x = q.top().second; q.pop();
  36. if(vst[x]) continue;
  37. vst[x] = 1;
  38. for(register int i = head[x]; i; i = edge[i].nex) {
  39. int y = edge[i].v;
  40. if(dist[y] > dist[x] + 1) dist[y] = dist[x] + 1, q.push(mp(-dist[y], y));
  41. }
  42. }
  43. #undef pi
  44. #undef mp
  45. }
  46. signed main() {
  47. //freopen("piggyback.in", "r", stdin);
  48. //freopen("piggyback.out", "w", stdout);
  49. b = read(), e = read(), p = read(), n = read(), m = read();
  50. for(register int i = 1; i <= m; ++i) {
  51. int u = read(), v = read();
  52. make_map(u, v), make_map(v, u);
  53. }
  54. Dijstra(1); for(register int i = 1; i <= n; ++i) dist1[i] = dist[i];
  55. Dijstra(2); for(register int i = 1; i <= n; ++i) dist2[i] = dist[i];
  56. Dijstra(n); for(register int i = 1; i <= n; ++i) distn[i] = dist[i];
  57. for(register int i = 1; i <= n; ++i) ans = min(ans, b * dist1[i] + e * dist2[i] + p * distn[i]);
  58. printf("%lld", ans);
  59. return 0;
  60. }

T2 Marathon

分析

考虑DP。

设:表示前头牛,跳过个点的最短距离。

枚举点,表示最后一步是从跑到的,则有方程:


边界条件:

  1. //The code is from dawn_sdy
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. inline int read() {
  5. int x = 0;
  6. char c = getchar();
  7. bool f = 0;
  8. while(!isdigit(c)) f |= (c == '-'), c = getchar();
  9. while(isdigit(c)) x = (x * 10) + (c ^ 48), c = getchar();
  10. return f ? -x : x;
  11. }
  12. const int maxn = 500 + 5;
  13. int n, k;
  14. struct Point {
  15. int x, y;
  16. }point[maxn];
  17. int f[maxn][maxn];
  18. inline int Get_Dis(int x, int y) { return abs(point[x].x - point[y].x) + abs(point[x].y - point[y].y); }
  19. int main() {
  20. //freopen("marathon.in", "r", stdin);
  21. //freopen("marathon.out", "w", stdout);
  22. n = read(), k = read();
  23. for(register int i = 1; i <= n; ++i) point[i].x = read(), point[i].y = read();
  24. memset(f, 0x3f, sizeof(f)), f[1][0] = 0;
  25. for(register int i = 1; i <= n; ++i)
  26. for(register int len = 0; len <= min(i - 2, k); ++len) {
  27. for(register int p = i - len - 1; p < i; ++p)
  28. f[i][len] = min(f[i][len], f[p][len - (i - p - 1)] + Get_Dis(i, p));
  29. }
  30. printf("%d", f[n][k]);
  31. return 0;
  32. }

T3 Cow Jog

分析

首先将所有点按照开始位置排序。

而显然,如果有一点无法追上前面的点,则此点后面的点也始终无法追上前面的点。

这就启发我们从后往前扫,记当前段最前面的点为,则我们只需要判断当前点是否能追上即可。

如果可以,则,如果不行那么把这点设为,继续操作。

  1. //The code is from dawn_sdy
  2. #include<bits/stdc++.h>
  3. #define int long long
  4. using namespace std;
  5. inline int read() {
  6. int x = 0;
  7. char c = getchar();
  8. bool f = 0;
  9. while(!isdigit(c)) f |= (c == '-'), c = getchar();
  10. while(isdigit(c)) x = (x * 10) + (c ^ 48), c = getchar();
  11. return f ? -x : x;
  12. }
  13. const int maxn = 1e5 + 5;
  14. int n, t;
  15. struct node {
  16. int st, speed;
  17. }a[maxn];
  18. inline bool operator <(node x, node y) {
  19. return x.st < y.st;
  20. }
  21. signed main() {
  22. // freopen("cowjog.in", "r", stdin);
  23. // freopen("cowjog.out", "w", stdout);
  24. n = read(), t = read();
  25. for(register int i = 1; i <= n; ++i) a[i].st = read(), a[i].speed = read();
  26. sort(a + 1, a + n + 1);
  27. int ans = n, now = n;
  28. for(register int i = n - 1; i >= 1; --i) {
  29. if( (a[i].speed - a[now].speed) * t >= a[now].st - a[i].st) ans--;
  30. else now = i;
  31. }
  32. printf("%lld", ans);
  33. return 0;
  34. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注