第十届山东省ACM省赛复现补题报告

C  Wandering Robot

1. 题意

  一个机器人在初始坐标(0,0),给定两个正整数n,k,分别代表机器人的指令数和循环次数,求机器人在移动过程中距原点的曼哈顿距离的最大值。

2. 题解

  以为最大值会在最后一次循环取到,一直wa到比赛结束。其实最大值有可能在第一次循环取到,例如:RRRRLLLLL 9 3,

维护一个最大值即可。

3. 代码

 1 #include<bits/stdc++.h>
 2 #define ll long long 
 3 using namespace std;
 4 const int maxn = 1e6 + 5;
 5 int t;
 6 int main() {
 7     ios::sync_with_stdio(false);
 8     cin >> t;
 9     while(t--) {
10         ll n, k;
11         cin >> n >> k;
12         string s;
13         cin >> s;
14         
15         ll u = 0;
16         ll r = 0;
17         ll mmax = 0;
18         //考虑在第一次循环出现 
19         for(int i = 0; i < n; i++) {
20             if(s[i] == 'U')
21                 u++;
22             if(s[i] == 'D')
23                 u--;
24             if(s[i] == 'L')
25                 r--;
26             if(s[i] == 'R')
27                 r++;
28             mmax = max(mmax, abs(u) + abs(r));
29         }
30         
31         //考虑在最后一次循环出现
32         u *= k - 1;
33         r *= k - 1; 
34         for(int i = 0; i < n; i++) {
35             if(s[i] == 'U')
36                 u++;
37             if(s[i] == 'D')
38                 u--;
39             if(s[i] == 'L')
40                 r--;
41             if(s[i] == 'R')
42                 r++;
43             mmax = max(mmax, abs(u) + abs(r));
44         }
45     
46         cout << mmax << endl;
47     }
48 
49     return 0;
50 }
View Code

D  Game on a Graph

1. 题意

  有k个人分成两组玩游戏,在一个有u个点,v条边的连通图中,每人轮流取走一条边,仍要保持图的连通,哪一组的人导致图无法连通,这一组就输了,输出赢家。

2. 题解

  u个点的连通图至少需要u-1条边,所以谁取走第u-1条边,谁就输了。在题目中,最多可以取走(v-u+1)% n条边,谁取走下一条边,谁就输了。

3. 代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e6 + 5;
 4 int t;
 5 int main() {
 6     scanf("%d", &t);
 7     while(t--) {
 8         int n, u, v, x = 0;
 9         char a[100005] = {0};
10         scanf("%d%s%d%d", &n, a, &u, &v);
11 
12         if(v >= u - 1) {
13             x = (v - u + 1) % n;
14         }
15         
16         while(v--) {        //空白输入 
17             scanf("%*d %*d");
18         }
19     
20         if(a[x] == '1') {   //下标从0开始 
21             cout << 2 << endl;
22         } else {
23             cout << 1 << endl;
24         }
25     }
26 
27     return 0;
28 }
View Code

H  Tokens on the Segments

 1. 题意

  在二维平面上有n条线段(线段可能为点),这些线段都平行于x轴,对于每个整数x轴坐标,都可以标记这个x轴坐标对应的一条线段,线段中的一个点被标记就代表这条线段被标记,问最多可以标记的线段数量。

  2.题解

     先把所有线段按左端点从小到大排序,左端点相同的按右端点从小到大排序,放入优先队列。因为要标记尽量多的线段,所以对于左端点相同的线段,标记最短的(贪心),队首的线段左端点未标记过则出队,标记左端点,ans加一,若队首的线段左端点已被标记,则将该线段左端点加一后将新线段入队,保证左端点小于等于右端点。

  3.代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct se {
 4     int l, r; 
 5     bool operator<(se a) const {
 6         if(l == a.l) {
 7             return r > a.r;
 8         }
 9         return l > a.l;
10     }
11 };
12 priority_queue<se> q;
13 int t;
14 int main() { 
15     scanf("%d", &t);
16     while(t--) {
17         int n, ans, x, y;
18         ans = 0;
19         while(!q.empty()) {
20             q.pop();
21         }
22         scanf("%d", &n);
23         while(n--) {
24             se t;
25             scanf("%d%d", &x, &y);
26             t.l = x;
27             t.r = y;
28             q.push(t); 
29         }
30         int k = 0;
31         while(!q.empty()) {
32             se u = q.top();
33             q.pop();
34             if(u.l == k) {    
35                 u.l++;
36                 if(u.l <= u.r)
37                     q.push(u);
38             }
39             else {
40                 k = u.l;
41                 ans++;
42             }
43         }
44         printf("%d
", ans);
45     }
46     
47     return 0;
48 }
View Code
原文地址:https://www.cnblogs.com/lvguapi/p/13747913.html