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\n", 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\n", 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\n", 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\n", 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] << "\n";
48             }
49             else
50             {
51                 cout << "-\n";
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], " \n"[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.

posted @ 2018-11-14 19:54  Dup4  阅读(290)  评论(0编辑  收藏  举报