第十四届浙江省赛

Posted tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十四届浙江省赛相关的知识,希望对你有一定的参考价值。

  题目真的是从易到难的顺序,而且跨度非常合理,只是看到榜单上后5题只有一支队做出来了一个,其他的没人做出来啊。。

A - Cooking Competition

水题。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int n, a;
 5 
 6 int main() {
 7     // freopen("in", "r", stdin);
 8     int T;
 9     scanf("%d", &T);
10     while(T--) {
11         scanf("%d", &n);
12         int ret = 0;
13         for(int i = 0; i < n; i++) {
14             scanf("%d", &a);
15             if(a == 1) ret++;
16             else if(a == 2) ret--;
17         }
18         if(ret == 0) puts("Draw");
19         else if(ret > 0) puts("Kobayashi");
20         else puts("Tohru");
21     }
22     return 0;
23 }

 

B - Problem Preparation

水题,细心点。特别是10~13题,差点被坑一小下。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 110;
 5 const int maxm = 1010;
 6 int n;
 7 int a[maxn];
 8 
 9 int main() {
10     // freopen("in", "r", stdin);
11     int T;
12     scanf("%d", &T);
13     while(T--) {
14         scanf("%d", &n);
15         for(int i = 1; i <= n; i++) {
16             scanf("%d", &a[i]);
17         }
18         if(n < 10 || n > 13) {
19             puts("No");
20             continue;
21         }
22         sort(a+1, a+n+1);
23         if(a[1] <= 0) {
24             puts("No");
25             continue;
26         }
27         int one = 0;
28         bool abflg = 0;
29         for(int i = 1; i <= n; i++) {
30             if(a[i] == 1) one++;
31         }
32         for(int i = 2; i < n; i++) {
33             if(a[i] - a[i-1] > 2) {
34                 abflg = 1;
35                 break;
36             }
37         }
38         if(one < 2 || abflg) {
39             puts("No");
40             continue;
41         }
42         puts("Yes");
43     }
44     return 0;
45 }

 

C - What Kind of Friends Are You?

读懂题就好,每一个人的答卷是一个01串,答案也是。拿去比对,看看有没有出现,出现超过1次的。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 1110;
 5 const int maxm = 22;
 6 int n, q, c;
 7 int m;
 8 int ans[maxn];
 9 int G[maxn];
10 map<string, int> id;
11 string name[maxn];
12 char tmp[maxm];
13 
14 int main() {
15     // freopen("in", "r", stdin);
16     int T, qs;
17     scanf("%d", &T);
18     while(T--) {
19         scanf("%d%d%d",&n,&q,&c);
20         id.clear();
21         memset(ans, 0, sizeof(ans));
22         memset(G, 0, sizeof(G));
23         for(int i = 1; i <= c; i++) {
24             scanf("%s", tmp);
25             id[tmp] = i;
26             name[i] = tmp;
27         }
28         for(int i = 1; i <= q; i++) {
29             scanf("%d", &m);
30             for(int j = 1; j <= m; j++) {
31                 scanf("%s", tmp);
32                 ans[id[tmp]] |= (1 << (i + 1));
33             }
34         }
35         for(int i = 1; i <= n; i++) {
36             for(int j = 1; j <= q; j++) {
37                 scanf("%d", &qs);
38                 if(qs == 1) G[i] |= (1 << (j + 1));
39             }
40         }
41         for(int i = 1; i <= n; i++) {
42             int cnt = 0;
43             int p;
44             for(int j = 1; j <= c; j++) {
45                 // cout << G[i] << " " << ans[j] << endl;
46                 if(G[i] == ans[j]) {
47                     cnt++;
48                     p = j;
49                 }
50             }
51             if(cnt != 1) puts("Let‘s go to the library!!");
52             else puts(name[p].c_str());
53         }
54     }
55     return 0;
56 }

 

D - Let‘s Chat

枚举a,b的所有区间,求交。长度-m+1就是那个区间的价值。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 typedef pair<LL, LL> pll;
 6 int n, m, x, y;
 7 LL ret;
 8 vector<pll> a, b;
 9 
10 bool cross(pll p, pll q, pll& ret) {
11     if(p > q) swap(p, q);
12     if(q.first <= p.second) {
13         ret.first = max(p.first, q.first);
14         ret.second = min(p.second, q.second);
15         return 1;
16     }
17     return 0;
18 }
19 
20 int main() {
21     // freopen("in", "r", stdin);
22     int T;
23     pll tmp;
24     scanf("%d", &T);
25     while(T--) {
26         a.clear(); b.clear();
27         ret = 0;
28         scanf("%d%d%d%d",&n,&m,&x,&y);
29         for(int i = 0; i < x; i++) {
30             scanf("%lld%lld",&tmp.first,&tmp.second);
31             a.push_back(tmp);
32         }
33         for(int i = 0; i < y; i++) {
34             scanf("%lld%lld",&tmp.first,&tmp.second);
35             b.push_back(tmp);
36         }
37         for(int i = 0; i < a.size(); i++) {
38             for(int j = 0; j < b.size(); j++) {
39                 if(cross(a[i], b[j], tmp)) {
40                     LL len = tmp.second - tmp.first + 1;
41                     if(len >= m)
42                         ret += len - (LL)m + 1;
43                 }
44             }
45         }
46         printf("%lld\n", ret);
47     }
48     return 0;
49 }

 

E - Seven Segment Display

数位dp,dp(l,sum)表示l位的时候各位的价值和,已知最大的位数是8位,每位最大价值是7,所以sum不会超过56。按照每位一个16进制数存好数位dp就行,8层。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int maxn = 22;
 6 const int maxm = 66;
 7 const LL up = 0xFFFFFFFF;
 8 int cost[maxn] = {6,2,5,5,4,5,6,3,7,6,6,5,4,5,5,4};
 9 LL l, r, n;
10 
11 int digit[maxm];
12 LL dp[maxn][maxm];
13 
14 LL dfs(int l, int sum, bool flag) {
15     if(l == 0) return (LL)sum;
16     if(!flag && ~dp[l][sum]) return dp[l][sum];
17     int pos = flag ? digit[l] : 15;
18     LL ret = 0;
19     for(int i = 0; i <= pos; i++) {
20         ret += dfs(l-1, sum+cost[i], flag&&(i==pos));
21     }
22     if(!flag) dp[l][sum] = ret;
23     return ret;
24 }
25 
26 LL f(LL x) {
27     for(int i = 1; i <= 8; i++) {
28         digit[i] = x % 16;
29         x /= 16;
30     }
31     return dfs(8, 0, true);
32 }
33 
34 int main() {
35     // freopen("in", "r", stdin);
36     int T;
37     scanf("%d", &T);
38     memset(dp, -1, sizeof(dp));
39     while(T--) {
40         LL ret = 0;
41         scanf("%lld %llx", &n, &l);
42         n--;
43         r = l + n;
44         if(r > up) {
45             LL mid = r % (up + 1);
46             ret = f(up) - f(l-1) + f(mid);
47         }
48         else ret = f(r) - f(l-1);
49         printf("%lld\n", ret);
50     }
51     return 0;
52 }

 

F - Heap Partition

贪心,维护一个数组a[]和一个set,set里维护的每一个元素分别维护了当前点作为父亲在某一个堆的序号和这个数字在数组a[]中的位置。还有一个vis数组标记每一个点的儿子数量。每读一个数a[j]就在set里找一个满足条件的a[i]>a[j]的最大的a[i]的对应set里的节点,插入后判断儿子有没有达到2,达到2则这个点就不要了。还要把它的儿子插进去。

群里问了下TLE的原因是这个题卡每一次循环的memset和clear,memset只需要memset n个点的位置就行了。把ret的vector每次输出完立刻clear就可以了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef pair<int, int> pii;
 5 
 6 typedef struct Node {
 7     int pos, id, val;
 8     Node() {}
 9     Node(int n, int i, int v) : pos(n), id(i), val(v) {}
10 
11 }Node;
12 
13 const int maxn = 100100;
14 int n, a[maxn];
15 set<Node> s;
16 set<Node>::iterator it;
17 vector<int> ret[maxn];
18 int vis[maxn];
19 
20 bool operator< (const Node& x, const Node& y) {
21     if(a[x.id] == a[y.id]) return x.id < y.id;
22     return a[x.id] < a[y.id];
23 }
24 
25 int main() {
26     // freopen("in", "r", stdin);
27     int T;
28     scanf("%d", &T);
29     while(T--) {
30         scanf("%d", &n);
31         memset(vis, 0, sizeof(int)*(n+4));
32         s.clear();
33         Node tmp;
34         int tot = 0;
35         for(int i = 1; i <= n; i++) {
36             scanf("%d", &a[i]);
37             tmp.id = i; tmp.val = a[i];
38             it = s.upper_bound(tmp);
39             if(it == s.begin()) {
40                 ret[tot].push_back(i);
41                 tmp = Node(tot++, i, a[i]);
42                 s.insert(tmp);
43             }
44             else {
45                 it--;
46                 tmp = *it;
47                 vis[tmp.id]++;
48                 if(vis[tmp.id] == 2) s.erase(it);
49                 tmp.id = i;
50                 s.insert(tmp);
51                 ret[tmp.pos].push_back(i);
52             }
53         }
54         printf("%d\n", tot);
55         for(int i = 0; i < tot; i++) {
56             printf("%d", ret[i].size());
57             for(int j = 0; j < ret[i].size(); j++) {
58                 printf(" %d", ret[i][j]);
59             }
60             printf("\n");
61         }
62         for(int i = 0; i < tot; i++) ret[i].clear();
63     }
64     return 0;
65 }

 

以上是关于第十四届浙江省赛的主要内容,如果未能解决你的问题,请参考以下文章

浙江省第十四届大学生程序设计竞赛总结

第十四届蓝桥杯大赛软件赛省赛JavaB组解析

第十四届蓝桥杯大赛软件赛省赛-试题 B---01 串的熵 解题思路+完整代码

第十四届华中科技大学程序设计竞赛决赛同步赛

记第十四届省赛参赛体会&第十三届

第十四届华中科技大学程序设计竞赛决赛同步赛 Beautiful Land