码迷,mamicode.com
首页 > 其他好文 > 详细

2018-2019 Всероссийская командная олимпиада школьников по программированию, интернет-тур + отборы регионов (ВКОШП 18, интернет-тур) Solution

时间:2018-11-11 19:14:05      阅读:4124      评论:0      收藏:0      [点我收藏+]

标签:open   --   print   break   eve   def   pair   连续   main   

A:

水。

技术分享图片
 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 
 7 const ll INFLL = 0x3f3f3f3f3f3f3f3f;
 8 
 9 ll n, m, h, w;
10 
11 ll solve()
12 {
13     ll cnt = 0;
14     ll tn = n, tm = m;
15     while(tn > h)
16     {
17         tn = (tn + 1)  >> 1;
18         cnt++;
19     }
20     while(tm > w)
21     {
22         tm = (tm + 1) >> 1;
23         cnt++;
24     }
25     return cnt;
26 }
27 
28 int main()
29 {
30     while(~scanf("%lld %lld %lld %lld", &n, &m, &h, &w))
31     {
32         ll ans = INFLL;
33         ans = min(ans, solve());
34         swap(h, w);
35         ans = min(ans, solve());
36         printf("%lld\n", ans);
37     }
38     return 0;
39 }
View Code

 

B:留坑。

 

C:留坑。

 

D:

题意:给出一棵树中每个点的度数,构造这一棵树

思路:将点按度数从大到小排序,每个点会有一个父亲,最多连出n - 1个点。

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 200010
 5 #define pii pair <int, int>
 6 int n, d[N], pos[N], fa[N]; 
 7 
 8 bool cmp (int a, int b) { return d[a] > d[b]; }
 9 
10 int main()
11 {
12     while (scanf("%d", &n) != EOF)
13     {
14         for (int i = 1; i <= n; ++i) scanf("%d", d + i), pos[i] = i; 
15         sort(pos + 1, pos + 1 + n, cmp);
16         for (int i = 2; i <= n; ++i) --d[pos[i]];
17         int id = 1;
18         for (int i = 1; i <= n; ++i)
19         {
20             while (d[pos[i]]--) 
21                 fa[pos[++id]] = pos[i];   
22         }
23         for (int i = 1; i <= n; ++i) if (i != pos[1])
24             printf("%d %d\n", fa[i], i);    
25     }
26     return 0;
27 }
View Code

 

E:

水。

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 1000010
 6 char s[N];
 7 
 8 int main()
 9 {
10     while (scanf("%s", s + 1) != EOF)
11     {
12         int cnt = 0;
13         for (int i = 1, len = strlen(s + 1); i <= len; ++i) cnt += (s[i] == A);
14         ll res = 0;
15         for (ll i = 1; ; ++i)
16         {
17             if (i * (i + 1) / 2 > cnt) break;
18             res = i;
19         }
20         printf("%lld\n", res);
21     }
22     return 0;
23 }
View Code

 

F:留坑。

 

G:

题意:给出一个n 要构造一个长度为n的序列,满足题目要求

思路:

如果是奇数

那么存在 起始点3   有 $2 \cdot 5 \cdot 6 = 3 \cdot 4 \cdot 5$

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int n;
 5 
 6 int main()
 7 {
 8     while (scanf("%d", &n) != EOF)
 9     {
10         if (n == 1) puts("NO");
11         else if (n & 1) 
12         {
13             puts("YES");
14             puts("3"); 
15             printf("-++");
16             for (int i = 4; i <= n; ++i) printf("%c", "+-"[i & 1]);
17             puts("");
18         }
19         else
20         {
21             puts("YES");
22             puts("1");
23             for (int i = 1; i <= n; ++i) printf("%c", "-+"[i & 1]);
24             puts("");
25         }
26     }
27     return 0;
28 }
View Code

 

H:

题意:给出0-9每个数字的个数,构造一个最大的数,使得任意连续三位连起来都是3的倍数。数字可以不用完

思路:先将所有数字模3

就是三种数字 0, 1, 2

再考虑 排列

显然 三个一组三个一组,三个中012至少出现一次,即012的全排列,一共6种,

再考虑 全放0, 1, 2 又是三种

再考虑 只有一位或者两位,可以任意摆放  

一共十种情况,去掉前导0之后取最大即可。

技术分享图片
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 100010
  5 int cnt[15], tmp_cnt[15], cntt[3], tmp_cntt[3], tar[3], Max[3], tmp_Max[3]; 
  6 char ans[10][N];     
  7 int pos;   
  8 
  9 void g()
 10 {
 11     for (int i = 0; i < 15; ++i) tmp_cnt[i] = cnt[i];
 12     for (int i = 0; i < 3; ++i) 
 13     {
 14         tmp_cntt[i] = cntt[i];
 15         tmp_Max[i] = Max[i];
 16     } 
 17 } 
 18 
 19 void f()
 20 {
 21     for (int i = 0; i < 15; ++i) cnt[i] = tmp_cnt[i];
 22     for (int i = 0; i < 3; ++i)
 23     {
 24         cntt[i] = tmp_cntt[i];
 25         Max[i] = tmp_Max[i]; 
 26     }
 27 } 
 28 
 29 void solve(int ide, int *tar)  
 30 { 
 31     pos = 0;
 32     while (1)
 33     {
 34         for (int i = 0; i < 3; ++i)
 35         {
 36             int id = tar[i];
 37             if (!cntt[id]) 
 38                 return; 
 39             if (cnt[Max[id]] == 0) 
 40             {
 41                 Max[id] = -1;  
 42                 for (int i = 9; i >= 0; --i) if (i % 3 == id && cnt[i]) 
 43                 {
 44                     Max[id] = i; 
 45                     break; 
 46                 }
 47                 if (Max[id] == -1) return; 
 48             }
 49             ans[ide][++pos] = Max[id] + 0;   
 50             --cntt[id]; 
 51             --cnt[Max[id]];  
 52         }
 53     }
 54 }
 55 
 56 void work(int id)
 57 {
 58     pos = 0; 
 59     while (cntt[id])
 60     {
 61         if (!cnt[Max[id]]) 
 62         {
 63             Max[id] = -1;
 64             for (int i = 9; i >= 0; --i) if (i % 3 == id && cnt[i])
 65             {
 66                 Max[id] = i;
 67                 break;    
 68             }
 69             if (Max[id] == -1) return;    
 70         }
 71         ans[id + 6][++pos] = Max[id] + 0;
 72         --cnt[Max[id]];
 73         --cntt[id];
 74     }
 75 }
 76 
 77 bool cmp(char *a, char *b) 
 78 {
 79     int lena = strlen(a + 1), lenb = strlen(b + 1);
 80     if (lena != lenb) return lena < lenb;
 81     for (int i = 1; i <= lena; ++i) if (a[i] != b[i])
 82         return a[i] < b[i];
 83     return 1;
 84 }
 85 
 86 void cle(int id)
 87 {
 88     int len = strlen(ans[id] + 1);
 89     pos = len + 1;
 90     for (int i = 1, len = strlen(ans[id] + 1); i <= len; ++i) if (ans[id][i] != 0)
 91     {
 92         pos = i;
 93         break;
 94     }
 95     if (pos == len + 1) 
 96     {
 97         ans[id][1] = 0;
 98         ans[id][2] = 0;
 99     }
100     else
101     {
102         for (int i = 1; i + pos - 1 <= len; ++i)
103             ans[id][i] = ans[id][i + pos - 1];
104         ans[id][len - pos + 2] = 0;
105     }
106 }
107 
108 int main()
109 {
110     while (scanf("%d", cnt) != EOF)
111     {
112         memset(cntt, 0, sizeof cntt); 
113         memset(Max, -1, sizeof Max);
114         memset(ans, 0, sizeof ans); 
115         for (int i = 1; i <= 9; ++i) scanf("%d", cnt + i);
116         for (int i = 0; i < 10; ++i) if (cnt[i])
117         {
118             cntt[i % 3] += cnt[i];
119             Max[i % 3] = i; 
120         } 
121         int res = 0;  
122         for (int i = 9; i >= 0 && res < 10; --i) if (cnt[i])
123         {
124             res = res * 10 + i;
125             if (res < 10 && cnt[i] > 1)
126                 res = res * 10 + i; 
127         } 
128         g(); 
129         pos = 0; 
130         while (res)
131         {
132             ans[9][++pos] = res % 10 + 0;  
133             res /= 10;
134         } 
135         ans[9][pos + 1] = 0; 
136         reverse(ans[9] + 1, ans[9] + pos + 1);  
137         tar[0] = 0, tar[1] = 1, tar[2] = 2;  
138         int ide = 0;
139         do
140         {
141             f();
142             solve(ide, tar); ans[ide][pos + 1] = 0; 
143             ++ide; 
144         } while (next_permutation(tar, tar + 3)); 
145         for (int i = 0; i < 3; ++i)
146         {
147             f(); pos = 0; work(i); 
148             ans[i + 6][pos + 1] = 0;  
149         } 
150         for (int i = 0; i < 10; ++i) cle(i);
151         pos = 0; 
152         for (int i = 1; i < 10; ++i) if (cmp(ans[pos], ans[i]))
153             pos = i;   
154         printf("%s\n", ans[pos] + 1); 
155     } 
156     return 0;
157 }
View Code

 

 

I:留坑。

 

J:留坑。

 

k:留坑。

 

L:水。

技术分享图片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 1010
 6 int n, k, x, cnt; 
 7 char s[15];
 8 ll Bit[15];
 9 
10 ll f(char *s)
11 {
12     ll res = 0;
13     for (int i = 1, len = strlen(s + 1); i <= len; ++i)
14         res = res * 10 + s[i] - 0;
15     return res;
16 }
17 
18 int main()
19 {
20     Bit[1] = 1;
21     for (int i = 2; i <= 10; ++i) Bit[i] = Bit[i - 1] * 10;
22     while (scanf("%d", &n) != EOF)
23     {
24         cnt = 0; ll Min = 0;
25         for (int i = 1; i <= n; ++i) 
26         {
27             scanf("%s", s + 1);
28             cnt = max(cnt, (int)strlen(s + 1));
29             Min = max(Min, f(s)); 
30         }
31         Min = max((ll)n, Min); 
32         Min = max(Min, Bit[cnt]); 
33         printf("%lld\n", Min);
34         for (int i = 1; i <= cnt; ++i) putchar(9); putchar(\n);
35     }
36     return 0;
37 }
View Code

 

2018-2019 Всероссийская командная олимпиада школьников по программированию, интернет-тур + отборы регионов (ВКОШП 18, интернет-тур) Solution

标签:open   --   print   break   eve   def   pair   连续   main   

原文地址:https://www.cnblogs.com/Dup4/p/9942889.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!