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

    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
    ", ans);
    37     }
    38     return 0;
    39 }
    View Code

    B:留坑。

    C:

    题意:有n道题目,总时间为T,对于每一道题目有完成的时间和可以得到的分数,做题策略为按照一定顺序做题,如果时间足够,那么就可以得到这道题的分数,安排一个顺序,使得得到的分数最少

    思路:如果总时间<=T 那么直接输出所有分数

    反之 ,考虑一定存在至少一道题目恰好不能被完成

    枚举这道题目,考虑所有时间小于这道题目的所有题目都要被完成

    对于每道题目,还需要枚举剩下的时间,使得它完不成

    那么排序之后枚举,左边的题目都要做完,右边的做01背包

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 2010
     6 #define pll pair <ll, ll> 
     7 #define INF 0x3f3f3f3f3f3f3f3f
     8 int n, m;
     9 pll a[N];
    10 ll dp[N][N];
    11 ll tot_time, tot_sco;
    12 
    13 int main()
    14 {
    15     while (scanf("%d%d", &n, &m) != EOF)
    16     {
    17         tot_time = 0, tot_sco = 0;
    18         for (int i = 1; i <= n; ++i) 
    19         {
    20             scanf("%lld%lld", &a[i].first, &a[i].second);
    21             tot_time += a[i].first;
    22             tot_sco += a[i].second;
    23         }
    24         if (tot_time <= m)
    25         {
    26             printf("%lld
    ", tot_sco);
    27             continue;
    28         }
    29         sort(a + 1, a + 1 + n);
    30         memset(dp, 0x3f, sizeof dp);    
    31         dp[n + 1][0] = 0;
    32         for (int i = n; i > 1; --i)
    33         { 
    34             for (int j = m; j >= a[i].first; --j)
    35                 dp[i][j] = min(dp[i][j], dp[i + 1][j - a[i].first] + a[i].second);
    36             for (int j = 0; j <= m; ++j) dp[i][j] = min(dp[i][j], dp[i + 1][j]);
    37         }
    38         ll step = 0, tot = 0, res = INF;
    39         for (int i = 1; i <= n; ++i)
    40         {
    41             ll tmp = INF;
    42             for (int j = m - step; j + a[i].first + step > m && j >= 0; --j) tmp = min(tmp, tot + dp[i + 1][j]);
    43             res = min(tmp, res); 
    44             step += a[i].first;
    45             tot += a[i].second;
    46         }
    47         printf("%lld
    ", res);
    48     }
    49     return 0;
    50 }
    View Code

    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
    ", 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
    ", 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
    ", ans[pos] + 1); 
    155     } 
    156     return 0;
    157 }
    View Code

    I:

    题意:阅读理解题。有一个类似游泳圈的东西,有四道大道路,内圈,外圈,上圈,下圈,每个国家有四个城市,四个城市分别属于四道大道路上,定义经过一个国家为至少经过一条该国家的道路,有从任意一个国家的内城市出发,经过所有城市的最短路径

    思路:考虑两种走法,

    一种是两个国家之间都走内圈,还有一种是间隔走,走一下内圈,走一下上圈,取Min

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 const double PI = acos(-1.0);
     6 ll r, R, n;
     7 
     8 int main()
     9 {
    10     while (scanf("%lld%lld%lld", &r, &R, &n) != EOF)
    11     {
    12         if (n == 1) 
    13         {
    14             printf("%.15f
    ", PI * r / 2);
    15             continue;
    16         }
    17         double len1 = (R - r) * 2.0 * PI / n; 
    18         double len2 = R * 2.0 * PI / n;
    19         double ans1 = (2 * n - 1) * PI * r / 2 + (n - 1) * len1;
    20         double ans2 = n * PI * r / 2 + (n / 2) * len2 + ((n - 1) / 2) * len1;
    21         printf("%.15f
    ", min(ans1, ans2));
    22     }
    23     return 0;
    24 }
    View Code

    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
    ", Min);
    34         for (int i = 1; i <= cnt; ++i) putchar('9'); putchar('
    ');
    35     }
    36     return 0;
    37 }
    View Code
  • 相关阅读:
    JMeter 关联
    JMeter MD5加密
    JMeter 时间函数
    JMeter 常用设置
    JMeter 服务器资源监控
    js制作列表滚动(有滚动条)
    js监听事件
    获取窗口大小 并自适应大小变化
    js 标签云
    js 显示数字不断增加
  • 原文地址:https://www.cnblogs.com/Dup4/p/9942889.html
Copyright © 2011-2022 走看看