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

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

fine 所有 reverse pre main spa 長度 圖片 perm

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