• 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) Solution


    A. Find a Number

    Solved By 2017212212083

    题意:$找一个最小的n使得n % d == 0 并且 n 的每一位数字加起来之和为s$

    思路:

    定义一个二元组$<d, s>$ 表示当前状态模d的值,以及每一位加起来的值

    跑最短路,从$<0, 0>  跑到 <0, s>$

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 1e5 + 10;
     6 const int INF = 0x3f3f3f3f;
     7 #define N 510
     8 #define M 5010
     9 
    10 int d, s, cnt;
    11 char ans[maxn];
    12 int dis[N][M];
    13 int inq[N][M];
    14 int vis[N][M];
    15 
    16 struct node{
    17     int remind;
    18     int sum;
    19     node(){}
    20     node(int remind, int sum) :remind(remind), sum(sum){}
    21 };
    22 
    23 void Init()
    24 {
    25     cnt = -1;
    26     memset(inq, 0, sizeof inq);
    27     memset(dis, 0x3f, sizeof dis);
    28     memset(vis, 0, sizeof vis);
    29 }
    30 
    31 void BFS()
    32 {
    33     queue<node>q;
    34     dis[0][0] = 0;
    35     q.push(node(0, 0));
    36     inq[0][0] = 1;
    37     while(!q.empty())
    38     {
    39         node st = q.front();
    40         q.pop();
    41         inq[st.remind][st.sum] = 0;
    42         for(int i = 0; i < 10; ++i)
    43         {
    44             node now = node((st.remind * 10 + i) % d, st.sum + i);
    45             if(now.sum > s) break;
    46             if(dis[now.remind][now.sum] > dis[st.remind][st.sum] + 1)
    47             {
    48                 dis[now.remind][now.sum] = dis[st.remind][st.sum] + 1;
    49                 if(!inq[now.remind][now.sum]) 
    50                 {
    51                     inq[now.remind][now.sum] = 1;
    52                     q.push(now);
    53                 }
    54             }
    55         }
    56     }
    57 }
    58 
    59 int DFS(int D,int S)
    60 {
    61     if(D == 0 && S == s) return 1;
    62     for(int i = 0; i < 10; ++i)
    63     {
    64         int td = (D * 10 + i) % d;
    65         int ts = S + i;
    66         if(ts > s) break;
    67         if(vis[td][ts]) continue;
    68         if(dis[D][S] + 1 != dis[td][ts]) continue;
    69         ans[++cnt] = i;
    70         if(DFS(td, ts)) return 1;
    71         --cnt;
    72     }
    73     vis[D][S] = 1;
    74     return 0;
    75 }
    76 
    77 int main()
    78 {
    79     while(~scanf("%d %d", &d, &s))
    80     {
    81         Init();
    82         BFS();
    83         if(dis[0][s] == INF)
    84         {
    85             puts("-1");
    86             continue;
    87         }
    88         DFS(0, 0);
    89         for(int i = 0; i <= cnt; ++i) printf("%d", ans[i]);
    90         puts("");
    91     }
    92     return 0;
    93 }
    View Code

    B. Berkomnadzor

    Unsolved.

    C. Cloud Computing

    Solved By Dup4

    题意:

    有一个人需要租用服务器,一共需要n天,每天要k个,供应商会提供一些供应方案,用四元组$<l, r, c, p>$ 表示方案。

    $l r  表示 供应的区间, c 表示l, r 区间内每天最多供应c个,p 表示每个服务器的价格$

    思路:

    考虑用线段树维护 两个值 Min 和 cnt  分别表示区间内最少的服务器需要个数以及区间内还需要购买服务器的天数

    对于供应方案,按价格排序之后,从小到大枚举,对于每个方案的$l, r$

    如果这个区间内所有还需要购买服务器的天中的 需要购买服务器的数量的最小值都 $> c$ 那么直接区间减即可。

    否则 先丢出不符合的,改为INF 再丢进去,标记为不再需要购买服务器,并加上贡献,每个点最多丢出一次。

    时间复杂度 $O(mlog^n + nlog^n)$

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define ll long long
      5 #define INF 0x3f3f3f3f
      6 #define N 1000010
      7 int n, k, m;
      8 struct qnode
      9 {
     10     int l, r, c, p;
     11     qnode () {}
     12     qnode (int l, int r, int c, int p) : l(l), r(r), c(c), p(p) {}
     13     void scan() { scanf("%d%d%d%d", &l, &r, &c, &p); }
     14     bool operator < (const qnode &r) const { return p < r.p; }
     15 }que[N]; 
     16 
     17 struct SEG
     18 {
     19     int lazy[N << 2], Min[N << 2], pos[N << 2], cnt[N << 2];
     20     struct node
     21     {
     22         int lazy, Min, pos, cnt;
     23         node () {}
     24         node (int lazy, int Min, int pos, int cnt) : lazy(lazy), Min(Min), pos(pos), cnt(cnt) {}
     25         void init() { lazy = 0; Min = INF; pos = 0; cnt = 0; }
     26         node operator + (const node &r) const
     27         {
     28             node res = node(0, INF, 0, 0);
     29             res.cnt = cnt + r.cnt;
     30             if (Min < r.Min)
     31             {
     32                 res.Min = Min;
     33                 res.pos = pos;
     34             }
     35             else
     36             {
     37                 res.Min = r.Min;
     38                 res.pos = r.pos;
     39             }    
     40             return res;
     41         }
     42     }a[N << 2], res;
     43     void build(int id, int l, int r)
     44     {
     45         a[id] = node(0, INF, 0, 0); 
     46         if (l == r) 
     47         {
     48             a[id] = node(0, k, l, 1);
     49             return;
     50         }    
     51         int mid = (l + r) >> 1;
     52         build(id << 1, l, mid);
     53         build(id << 1 | 1, mid + 1, r);
     54         a[id] = a[id << 1] + a[id << 1 | 1];
     55     }
     56     void change(int id, int lazy)
     57     {
     58         a[id].lazy += lazy;
     59         a[id].Min += lazy;
     60     }
     61     void pushdown(int id)
     62     {
     63         if (!a[id].lazy) return;
     64         change(id << 1, a[id].lazy);
     65         change(id << 1 | 1, a[id].lazy);
     66         a[id].lazy = 0;
     67     }
     68     void update(int id, int l, int r, int ql, int qr, int val)
     69     {
     70         if (l >= ql && r <= qr) 
     71         {
     72             a[id].Min += val;
     73             a[id].lazy += val;
     74             return;
     75         }
     76         pushdown(id);
     77         int mid = (l + r) >> 1;
     78         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
     79         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
     80         a[id] = a[id << 1] + a[id << 1 | 1]; 
     81     }
     82     void update(int id, int l, int r, int pos)
     83     {
     84         if (l == r) 
     85         {
     86             a[id].Min = INF;
     87             a[id].cnt = 0;
     88             return;
     89         }
     90         pushdown(id);
     91         int mid = (l + r) >> 1;
     92         if (pos <= mid) update(id << 1, l, mid, pos);
     93         else update(id << 1 | 1, mid + 1, r, pos);
     94         a[id] = a[id << 1] + a[id << 1 | 1];
     95     }
     96     void query(int id, int l, int r, int ql, int qr)
     97     {
     98         if (l >= ql && r <= qr) 
     99         {
    100             res = res + a[id];
    101             return;
    102         }
    103         pushdown(id);
    104         int mid = (l + r) >> 1;
    105         if (ql <= mid) query(id << 1, l, mid, ql, qr);
    106         if (qr > mid) query(id << 1 | 1, mid + 1, r, ql, qr);
    107         a[id] = a[id << 1] + a[id << 1 | 1];
    108     }
    109 }seg;
    110 
    111 int main()
    112 {
    113     while (scanf("%d%d%d", &n, &k, &m) != EOF)
    114     {
    115         for (int i = 1; i <= m; ++i) que[i].scan();
    116            sort(que + 1, que + 1 + m);
    117         seg.build(1, 1, n);
    118         ll res = 0;
    119         for (int i = 1, l, r, c, p; i <= m; ++i)
    120         {
    121             l = que[i].l, r = que[i].r, c = que[i].c, p = que[i].p;
    122             while (1)
    123             {
    124                 seg.res.init();
    125                 seg.query(1, 1, n, l, r);
    126                 if (seg.res.cnt == 0) break;
    127                 if (seg.res.Min <= c)
    128                 {
    129                     res += (ll)p * seg.res.Min;
    130                     seg.update(1, 1, n, seg.res.pos);
    131                 }
    132                 else
    133                 {
    134                     res += (ll)p * seg.res.cnt * c;
    135                     seg.update(1, 1, n, l, r, -c);
    136                     break;
    137                 }
    138             }
    139         }    
    140         printf("%lld
    ", res); 
    141     }
    142     return 0;
    143 }
    View Code

    D. Garbage Disposal

    水。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 int main()
     8 {
     9     ll n, k;
    10     while(~scanf("%lld %lld", &n, &k))
    11     {
    12         ll ans = 0;
    13         ll res = 0;
    14         for(int i = 1; i <= n; ++i)
    15         {
    16             ll x;
    17             scanf("%lld", &x);
    18             if(res > 0)
    19             {
    20                 res += x;
    21                 if(res >= k) 
    22                 {
    23                     ans += res / k;
    24                     res %= k;
    25                 }
    26                 else 
    27                 {
    28                     res = 0;
    29                     ans++;
    30                 }
    31             }
    32             else
    33             {
    34                 res += x;
    35                 ans += res / k;
    36                 res %= k;
    37             }
    38         }
    39         if(res)
    40         {
    41             ans += res % k == 0 ? res / k : res / k + 1;
    42         }
    43         printf("%lld
    ", ans);
    44     }
    45     return 0;
    46 }
    View Code

    E. Getting Deals Done

    Solved By 2017212212083 & Dup4

    题意:

    有一个任务序列,每个任务有一个完成时间,在做任务的时候有这样一个规则,定义一个d,对于所有时间小于等于d的任务都要做,并且每做完m个,都要休息,休息时间为这m个任务的总时间,如果一个任务做不完,这个任务不算数。给出一个总时间T, n, m

    以及每个任务的时间,求最大的任务数,以及d

    思路:

    二分任务数x, 显然我们要做的任务是排序后前x个,将d设为第x个的时间,按规则遍历看是否合法即可。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 200010
     6 int t, n, m; ll T;  
     7 int p[N], b[N]; 
     8 
     9 bool check(int x)
    10 {
    11     int dd = p[x]; 
    12     ll tmp = 0, TT = T; int cnt = 0, tot = 0;
    13     for (int i = 1; i <= n; ++i) if (b[i] <= dd)
    14     {
    15         if (TT - b[i] >= 0)
    16         {
    17             ++cnt; TT -= b[i];
    18             tmp += b[i];
    19             ++tot;
    20         }
    21         else return tot >= x;
    22         if (cnt == m)
    23         {
    24             cnt = 0;
    25             TT -= tmp;
    26             tmp = 0;
    27         }
    28     }
    29     if (tot >= x)
    30     {
    31         return true;
    32     }
    33     return false;
    34 }
    35 
    36 int main()
    37 {
    38     scanf("%d", &t);
    39     while (t--)
    40     {
    41         scanf("%d%d%lld", &n, &m, &T);
    42         for (int i = 1; i <= n; ++i) scanf("%d", p + i), b[i] = p[i];
    43         sort(p + 1, p + 1 + n);
    44         p[0] = T;
    45         int l = 0, r = n, res = -1;  
    46         while (r - l >= 0)
    47         {
    48             int mid = (l + r) >> 1;
    49             if (check(mid)) 
    50             {
    51                 res = mid;
    52                 l = mid + 1;
    53             }
    54             else 
    55                 r = mid - 1;
    56         }
    57         printf("%d %d
    ", res, p[res]);
    58     }
    59     return 0;
    60 }
    View Code

    F. Debate

    水。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 400010
     5 int n, a[N], cnt[4]; 
     6 priority_queue <int> pq[4];
     7 
     8 void init()
     9 {
    10     memset(cnt, 0, sizeof cnt);
    11     for (int i = 0; i < 4; ++i) while (!pq[i].empty()) pq[i].pop();
    12 }
    13 
    14 int main()
    15 {    
    16     while (scanf("%d", &n) != EOF)
    17     {
    18         init(); int res = 0;
    19         for (int i = 1, x; i <= n; ++i) 
    20         {
    21             scanf("%02d%d", &x, a + i);
    22             if (x == 11) x = 3; 
    23             else if (x == 10) x = 2;
    24             ++cnt[x]; 
    25             if (x == 3) res += a[i];
    26             else pq[x].push(a[i]);
    27         }
    28         int limit = min(cnt[1], cnt[2]);
    29         for (int i = 1; i <= 2; ++i) for (int j = 0; j < limit; ++j) 
    30         {
    31             res += pq[i].top(); pq[i].pop();
    32         }
    33         for (int i = 1; i <= 2; ++i) while (!pq[i].empty())
    34         {
    35             pq[0].push(pq[i].top()); pq[i].pop();
    36         }
    37         limit = min(cnt[3], (int)pq[0].size());
    38         for (int i = 0; i < limit; ++i) 
    39         {
    40             res += pq[0].top(); pq[0].pop();
    41         }
    42         printf("%d
    ", res);
    43     }
    44     return 0;
    45 }
    View Code

    G. Monsters and Potions

    Unsolved.

    H. BerOS File Suggestion

    水。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 map<string, int>mp1;
     6 map<string, string>mp2;
     7 
     8 int n, q;
     9 string s;
    10 
    11 int main()
    12 {
    13     ios::sync_with_stdio(false);
    14     cin.tie(0);
    15     cout.tie(0);
    16     while(cin >> n)
    17     {
    18         mp1.clear();
    19         mp2.clear();
    20         for(int i = 1; i <= n; ++i)
    21         {
    22             cin >> s;
    23             int len = s.length();
    24             set<string>st;
    25             for(int i = 0; i < len; ++i)
    26             {
    27                 string tmp = "";
    28                 for(int j = i; j < len; ++j)
    29                 {
    30                     tmp += s[j];
    31                     st.insert(tmp);
    32                 }
    33             }
    34             for(auto it : st)
    35             {
    36                 mp1[it]++;
    37                 mp2[it] = s;
    38             }
    39         }
    40         cin >> q;
    41         while(q--)
    42         {
    43             cin >> s;
    44             cout << mp1[s] << " ";
    45             if(mp1[s])
    46             {
    47                 cout << mp2[s] << "
    ";
    48             }
    49             else
    50             {
    51                 cout << "-
    ";
    52             }
    53         }
    54     }
    55     return 0;
    56 }
    View Code

    I. Privatization of Roads in Berland

    Unsolved.

    J. Streets and Avenues in Berhattan

    Unsolved.

    K. Video Posts

    水。

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 1e5 + 10;
     6 
     7 int n, k;
     8 int arr[maxn];
     9 int sum;
    10 
    11 void solve()
    12 {
    13     if(sum % k)
    14     {
    15         puts("No");
    16         return ;
    17     }
    18     vector<int>vec;
    19     int res = 0;
    20     int st = 0;
    21     for(int i = 1; i <= n; ++i)
    22     {
    23         res += arr[i];
    24         if(res > sum / k)
    25         {
    26             puts("No");
    27             return ;
    28         }
    29         else if(res == sum / k)
    30         {
    31             vec.push_back(i - st);
    32             st = i;
    33             res = 0;
    34         }
    35     }
    36     puts("Yes");
    37     for(int i = 0, len = vec.size(); i < len; ++i)
    38     {
    39         printf("%d%c", vec[i], " 
    "[i == len - 1]);
    40     }
    41 }
    42 
    43 int main()
    44 {
    45     while(~scanf("%d %d", &n ,&k))
    46     {
    47         sum = 0;
    48         for(int i = 1; i <= n; ++i)
    49         {
    50             scanf("%d", arr + i);
    51             sum += arr[i];    
    52         }
    53         solve();
    54     }
    55     return 0;
    56 }
    View Code

    L. Odd Federalization

    Unsolved.

    M. Algoland and Berland

    Unsolved.

  • 相关阅读:
    互联网商业数据分析(二十七):运营分析(三)用户分层
    鲲鹏服务器上跑dpdk kni bug
    dpdk 网卡顺序
    dpvs ipvsadm.c:114:10: fatal error: popt.h: No such file or directory
    dpvs keepalived编译出错
    ps查看线程所在的cpu + pstack 线程+ strace 线程
    查看内核模块加载时参数
    dpdk kni二
    dpdk eal 参数
    dpdk project gdb
  • 原文地址:https://www.cnblogs.com/Dup4/p/9960001.html
Copyright © 2020-2023  润新知