2019-2020 ICPC North-Western Russia Regional Contest

Posted jhseng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019-2020 ICPC North-Western Russia Regional Contest相关的知识,希望对你有一定的参考价值。

最近事务繁多,很久没写文章了。正好趁刚换新队友的第一场训练,记录一下。

题目中规中矩。


A:

solver:lzh

完全没看,好像是个傻逼题。

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main() {
 4     int a, b, n; scanf("%d%d%d", &a, &b, &n);
 5     int c = b, d = a, ans = 0, cur = 1;
 6     while (c != n || d != n) {
 7         if (!cur) {
 8             c += b - a;
 9             if (c > n)c = n;
10         } else {
11             d += b - a;
12             if (d > n)d = n;
13         }
14         cur ^= 1;
15         ans++;
16     }
17     printf("%d
", ans);
18 }
View Code

E:

solver:zyh、lzh

给定一棵树,树上有若干个重要点。问是否存在一个点到所有重要点距离相等。

树的直径瞎搞。

技术图片
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int>v[200010];
int mark[200010], ismark[200010];
int st[200010], num = 0, ans = 0, ansn;
int dep[200010];
void dfs1(int x, int pre, int d) {
    st[++num] = x;
    if (ismark[x] && ans < d)ans = d, ansn = st[num + 1 >> 1];
    for (auto i : v[x])
        if (i != pre)
            dfs1(i, x, d + 1);
    num--;
}
void dfs2(int x, int pre, int d) {
    dep[x] = d;
    for (auto i : v[x])
        if (i != pre)
            dfs2(i, x, d + 1);
}
int main() {
    int n, m; scanf("%d%d", &n, &m);
    for (int i = 2; i <= n; i++) {
        int x, y; scanf("%d%d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for (int i = 1; i <= m; i++)scanf("%d", &mark[i]), ismark[mark[i]]++;
    if (m == 1) {
        printf("YES
1
");
        return 0;
    }
    dfs1(mark[1], -1, 0);
    if (ans & 1) {
        printf("NO
"); return 0;
    }
    dfs2(ansn, -1, 1);
    for (int i = 2; i <= m; i++)
        if (dep[mark[i - 1]] != dep[mark[i]]) {
            printf("NO
");
            return 0;
        }
    printf("YES
%d
", ansn);
}
View Code

H:

solver:czq

给定n个数,要求把这n个数分成连续的尽量少的块,并且每块和<=t。

由于有多个询问,故可以预处理出每个询问能装多少个数。然后每个询问直接模拟统计答案。

技术图片
 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson (curpos<<1)
15 #define rson (curpos<<1|1)
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 const int maxn = 1e6 + 10;
21 int n, a[maxn], pos[maxn], cnt[maxn], preSum[maxn], maxx;
22 
23 int solve(int x) {
24     if (x < maxx) return -int_inf;
25     if (cnt[x]) return cnt[x];
26     int res = 0, i = 0;
27     while (i < n) {
28         res += x;
29         res = min(res, 1000000);
30         i = pos[res];
31         res = preSum[i];
32         cnt[x]++;
33     }
34     return cnt[x];
35 }
36 
37 int main() {
38     scanf("%d", &n);
39     for (int i = 1; i <= n; i++) {
40         scanf("%d", &a[i]);
41         maxx = max(maxx, a[i]);
42         preSum[i] = preSum[i - 1] + a[i];
43         for (int j = preSum[i - 1]; j < preSum[i]; j++) pos[j] = i - 1;
44     }
45     for (int i = preSum[n]; i <= 1000000; i++) pos[i] = n;
46     int q; scanf("%d", &q);
47     while (q--) {
48         int x; scanf("%d", &x);
49         int ret = solve(x);
50         if (ret != -int_inf) printf("%d
", solve(x));
51         else puts("Impossible");
52     }
53     return 0;
54 }
View Code

I:

solver:czq

给定三维空间内的n个点,要求构造一个尽量小的四棱锥(底面两边与坐标轴平行,且锥面与底面夹角为45度),使得该四棱锥能包含n个点。

因为锥面与底面夹角为45度,故可以拆开分别考察xOz和yOz两个平面,构造出两个等腰直角三角形之后再合并答案。

技术图片
 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(p,b) sort(p+1,p+1+b)
 9 #define rep1(i,p,b) for(int i=p;i<=b;++i)
10 #define rep0(i,p,b) for(int i=p;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson (curpos<<1)
15 #define rson (curpos<<1|1)
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 const int maxn = 1e3 + 10;
21 struct Point {
22     int x, y, z;
23 } p[maxn];
24 int n, l1 = INT_MAX, l2 = INT_MAX, r1 = -INT_MAX, r2 = -INT_MAX;
25 
26 int main() {
27     scanf("%d", &n);
28     for (int i = 1; i <= n; i++) scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].z);
29     for (int i = 1; i <= n; i++) {
30         l1 = min(p[i].x - p[i].z, l1); l2 = min(p[i].y - p[i].z, l2);
31         r1 = max(p[i].x + p[i].z, r1); r2 = max(p[i].y + p[i].z, r2);
32     }
33     int currx = l1 + r1 >> 1, curry = l2 + r2 >> 1;
34     int h1 = max(currx - l1, curry - l2), h2 = max(r1 - currx, r2 - curry);
35     printf("%d %d %d
", currx, curry, max(h1, h2));
36     return 0;
37 }
View Code

J:

solver:czq

显然倒着构造会好构造很多。对于点对(i,j),计算所有的k(i<k<j)对a[i][j]的贡献即可。如果不一样,说明点i与点j之间存在边。

技术图片
 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(ans,b) sort(ans+1,ans+1+b)
 9 #define rep1(i,ans,b) for(int i=ans;i<=b;++i)
10 #define rep0(i,ans,b) for(int i=ans;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson (curpos<<1)
15 #define rson (curpos<<1|1)
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 const int maxn = 510;
21 int n, a[maxn][maxn], ans[maxn][maxn];
22 
23 int main() {
24     scanf("%d", &n);
25     for (int i = 1; i <= n; i++)
26         for (int j = 1; j <= n; j++)
27             scanf("%1d", &a[i][j]);
28     for (int i = n - 1; i >= 1; i--)
29         for (int j = i; j <= n; j++) {
30             int contribute = 0;
31             for (int k = i + 1; k < j; k++) contribute = (contribute + ans[i][k] * a[k][j]) % 10;
32             if (contribute != a[i][j]) ans[i][j] = 1;
33         }
34     for (int i = 1; i <= n; i++) {
35         for (int j = 1; j <= n; j++) printf("%d", ans[i][j]);
36         puts("");
37     }
38     return 0;
39 }
View Code

K:

solver:lzh、czq

细节贪心题,枚举A的最大可能上下边界,得出可行的左右边界,再分割剩下的区域。

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef pair<int, char> pic;
 5 typedef pair<int, int> pii;
 6 char s[1010][1010], ans[1010][1010];
 7 pii p[30];
 8 vector<pic> v[1010];
 9 int pt[1010];
10 void solve(pii l, pii r) {
11     for (int i = 1; i <= 1000; i++)v[i].clear(), pt[i] = 0;
12     for (int i = 2; i <= 26; i++)
13         if (l.first <= p[i].first && p[i].first <= r.first &&
14                 l.second <= p[i].second && p[i].second <= r.second)
15             v[p[i].first].push_back(make_pair(p[i].second, i + a - 1));
16 
17     for (int i = l.first; i <= r.first; i++)
18         sort(v[i].begin(), v[i].end());
19 
20     for (int i = l.first; i <= r.first; i++)
21         if (v[i].size() == 0 && pt[i - 1]) {
22             for (int j = l.second; j <= r.second; j++)ans[i][j] = ans[i - 1][j];
23             pt[i] = 1;
24         } else if (v[i].size() == 1) {
25             for (int j = l.second; j <= r.second; j++)ans[i][j] = v[i][0].second;
26             pt[i] = 1;
27         } else if (v[i].size() > 1) {
28             pt[i] = 1;
29             int pre = l.second;
30             for (auto j : v[i]) {
31                 for (; pre <= j.first; pre++)ans[i][pre] = j.second;
32             }
33 
34             for (; pre <= r.second; pre++)ans[i][pre] = ans[i][pre - 1];
35         }
36 
37     for (int i = r.first; i >= l.first; i--)
38         if (!pt[i])
39             for (int j = l.second; j <= r.second; j++)
40                 ans[i][j] = ans[i + 1][j];
41 }
42 int main() {
43     int n, m; scanf("%d%d", &n, &m);
44     pii A;
45     for (int i = 1; i <= n; i++) {
46         scanf("%s", s[i] + 1);
47         for (int j = 1; j <= m; j++)
48             if (s[i][j] != .) {
49                 if (s[i][j] != A) {
50                     p[s[i][j] - A + 1] = make_pair(i, j);
51                     v[i].push_back(make_pair(j, s[i][j] + a - A));
52                 } else A = make_pair(i, j);
53             }
54     }
55 
56     int tmp = 0;
57     pii L, R;
58     for (int i = 1; i <= n; i++) {
59         priority_queue<int>l;
60         priority_queue<int, vector<int>, greater<int>>r;
61         l.push(0);
62         r.push(m + 1);
63         for (int j = i; j <= n; j++) {
64             int gg = 0;
65             for (int k = 2; k <= 26; k++)
66                 if (i <= p[k].first && p[k].first <= j) {
67                     if (p[k].second == A.second) {
68                         gg++; break;
69                     } else if (p[k].second < A.second)l.push(p[k].second);
70                     else r.push(p[k].second);
71                 }
72             if (gg)break;
73             if (i <= A.first && A.first <= j && l.top() < A.second && A.second < r.top()
74                     && (j - i + 1) * (r.top() - l.top() - 1) > tmp) {
75                 tmp = (j - i + 1) * (r.top() - l.top() - 1);
76                 L = make_pair(i, l.top() + 1);
77                 R = make_pair(j, r.top() - 1);
78             }
79         }
80     }
81     if (L.first != 1)solve(make_pair(1, 1), make_pair(L.first - 1, m));
82     if (R.first != n)solve(make_pair(R.first + 1, 1), make_pair(n, m));
83     if (L.second != 1)solve(make_pair(L.first, 1), make_pair(R.first, L.second - 1));
84     if (R.second != m)solve(make_pair(L.first, R.second + 1), make_pair(R.first, m));
85 
86     for (int i = 2; i <= 26; i++)ans[p[i].first][p[i].second] = A + i - 1;
87     for (int i = L.first; i <= R.first; i++)
88         for (int j = L.second; j <= R.second; j++)
89             ans[i][j] = a;
90     ans[A.first][A.second] = A;
91 
92     for (int i = 1; i <= n; i++, printf("
"))
93         for (int j = 1; j <= m; j++)
94             printf("%c", ans[i][j]);
95 }
View Code

M:

solver:zyh

没看,签到。

技术图片
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <map>
 4 using namespace std;
 5 int a[10001];
 6 map<int, int> M;
 7 int main() {
 8     int T;
 9     long long ans = 0;
10     scanf("%d", &T);
11     while (T--) {
12         int n;
13         M.clear();
14         ans = 0;
15         scanf("%d", &n);
16         for (int i = 0; i < n; ++i) {
17             scanf("%d", &a[i]);
18             M[a[i]]++;
19         }
20         for (int j = 0; j < n; ++j) {
21             M[a[j]]--;
22             if (M[a[j]] == 0) M.erase(a[j]);
23             for (int i = 0; i < j; ++i) {
24                 int k = 2 * a[j] - a[i];
25 
26                 if (M.find(k) != M.end()) ans += M[k];
27             }
28         }
29         printf("%lld
", ans);
30     }
31 }
View Code

 

 

以上是关于2019-2020 ICPC North-Western Russia Regional Contest的主要内容,如果未能解决你的问题,请参考以下文章

2019-2020 ICPC, Asia Jakarta Regional Contest

2019-2020 ICPC, Asia Jakarta Regional Contest C. Even Path

2019-2020 ICPC, NERC, Southern and Volga Russian Regional Contest

2019-2020 ICPC, Asia Jakarta Regional Contest H. Twin Buildings

2019-2020 ACM-ICPC Brazil Subregional Programming Contest (7/10)

比赛:ICPC Asia Taipei-Hsinchu Regional 2019 2020.4.1