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 }

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 }

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 }

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 }

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 }

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 }

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 }

L. Odd Federalization

Unsolved.

M. Algoland and Berland

Unsolved.

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

时间: 2024-10-29 12:07:27

2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) Solution的相关文章

2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror) 体验记

原文链接https://www.cnblogs.com/zhouzhendong/p/CF1070.html 比赛网址:http://codeforces.com/contest/1070 感受 本来只打算玩玩的. 结果玩的海星. 我做 A 题的时候可能比较浮躁吧,各种傻错误,爆了 7 个罚时. 我 A 还没过,cly 神仙已经把 CDK 切光了. 4点半过一会儿,各自回家.cly 要剃头,就咕咕咕了.我本来也要剃的,后来临时决定先打题. 然后过了 A ,顺手切掉了 H 和 F ,开了 E ,猜

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

http://codeforces.com/contest/1070 A 给你一个d和s,求一个最小的数,使的能整除d,并且每位数的和为s. 如果确定了某n位数取模d的值,那么再计算同样的n位数,取模d也是相同的值时,就多此一举了.比如10%2 == 0  20%2 == 0  同样是两位数,取模2都是等于0.所以取最小的就可以了. 1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const

2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror) Partial Solution

从这里开始 题目列表 瞎扯 Problem A Find a Number Problem B Berkomnadzor Problem C Cloud Computing Problem D Garbage Disposal Problem E Getting Deals Done Problem F Debate Problem G Monsters and Potions Problem H BerOS File Suggestion Problem I Privatization of

2018-2019 ICPC, NEERC, Southern Subregional Contest

目录 2018-2019 ICPC, NEERC, Southern Subregional Contest (Codeforces 1070) A.Find a Number(BFS) C.Cloud Computing(线段树) D.Garbage Disposal(模拟) E.Getting Deals Done(二分) F.Debate(贪心) H.BerOS File Suggestion(后缀自动机) I.Privatization of Roads in Berland(网络流)

模拟赛小结:2014-2015 ACM-ICPC, NEERC, Southern Subregional Contest

2014-2015 ACM-ICPC, NEERC, Southern Subregional Contest 2019年10月11日 15:30-20:30(Solved 6,Penalty 740) 国庆咸鱼十来天,回来又过了快一个星期,终于和队友约上了模拟赛.(周三拖周四,因为队(fei)友(zhai)们要跑1000米,又拖到周五QAQ) I:00:04.开场翻翻题目,机智如我很快找到一个贪心. D:00:36.看了看现场榜,有人交D.F和M,lh同学已经开F去了,xk同学说他M思路差不多

D. Dog Show 2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest, qualification stage (Online Mirror, ACM-ICPC Rules, Teams Preferred)

http://codeforces.com/contest/847/problem/D 巧妙的贪心 仔细琢磨... 像凸包里的处理 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <time.h> 6 #include <string> 7 #include <set> 8 #includ

NEERC Southern Subregional 2012

NEERC Southern Subregional 2012 Problem B. Chess Championship 题目描述:有两个序列\(a, b\),两个序列都有\(n\)个数,并且这\(2n\)个数两两不同,现在要将这两个序列里的数两两配对,组成\(n\)个数对,要求数对中\(a\)的数比\(b\)的数大的数对个数要比其它的多\(m\)个.问方案数. solution 将这\(2n\)个数从小到大排,预处理出前\(i\)个数中\(a, b\)的个数\(suma, sumb\), \

2013-2014 ACM-ICPC, NEERC, Eastern Subregional Contest PART (7/10)

\[2013-2014\ ACM-ICPC,\ NEERC,\ Eastern\ Subregional\ Contest\] \(A.Podracing\) \(B.The\ battle\ near\ the\ swamp\) 签到 //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<bits/stdc++.h> using namespace std; function<void(

ACM ICPC 2011–2012, NEERC, Northern Subregional Contest J. John’s Inversions(合并排序求逆序数对数)

题目链接:http://codeforces.com/gym/100609/attachments 题目大意:有n张牌,每张牌有红色和蓝色两面,两面分别写了一些数字,同种颜色的任意两个数字若排在前面的数字比排在后面的数字大就叫做一对逆序数.求怎样排序得到的逆序数对最少. 解题思路:其中一种颜色的数字是顺序且这种颜色数字相同时对应的另一种颜色的数字是顺序时得到的逆序数对数最少.难点在于求逆序数对数.因为数量很大O(n^2)复杂度不能满足,这里根据合并排序的原理求解每个数字前面有多少个比它大的数字,