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

2022-11-12,,,,

A. Find a Number

Solved By 2017212212083

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

思路:

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

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

 #include<bits/stdc++.h>

 using namespace std;

 const int maxn = 1e5 + ;
const int INF = 0x3f3f3f3f;
#define N 510
#define M 5010 int d, s, cnt;
char ans[maxn];
int dis[N][M];
int inq[N][M];
int vis[N][M]; struct node{
int remind;
int sum;
node(){}
node(int remind, int sum) :remind(remind), sum(sum){}
}; void Init()
{
cnt = -;
memset(inq, , sizeof inq);
memset(dis, 0x3f, sizeof dis);
memset(vis, , sizeof vis);
} void BFS()
{
queue<node>q;
dis[][] = ;
q.push(node(, ));
inq[][] = ;
while(!q.empty())
{
node st = q.front();
q.pop();
inq[st.remind][st.sum] = ;
for(int i = ; i < ; ++i)
{
node now = node((st.remind * + i) % d, st.sum + i);
if(now.sum > s) break;
if(dis[now.remind][now.sum] > dis[st.remind][st.sum] + )
{
dis[now.remind][now.sum] = dis[st.remind][st.sum] + ;
if(!inq[now.remind][now.sum])
{
inq[now.remind][now.sum] = ;
q.push(now);
}
}
}
}
} int DFS(int D,int S)
{
if(D == && S == s) return ;
for(int i = ; i < ; ++i)
{
int td = (D * + i) % d;
int ts = S + i;
if(ts > s) break;
if(vis[td][ts]) continue;
if(dis[D][S] + != dis[td][ts]) continue;
ans[++cnt] = i;
if(DFS(td, ts)) return ;
--cnt;
}
vis[D][S] = ;
return ;
} int main()
{
while(~scanf("%d %d", &d, &s))
{
Init();
BFS();
if(dis[][s] == INF)
{
puts("-1");
continue;
}
DFS(, );
for(int i = ; i <= cnt; ++i) printf("%d", ans[i]);
puts("");
}
return ;
}

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)$

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define INF 0x3f3f3f3f
#define N 1000010
int n, k, m;
struct qnode
{
int l, r, c, p;
qnode () {}
qnode (int l, int r, int c, int p) : l(l), r(r), c(c), p(p) {}
void scan() { scanf("%d%d%d%d", &l, &r, &c, &p); }
bool operator < (const qnode &r) const { return p < r.p; }
}que[N]; struct SEG
{
int lazy[N << ], Min[N << ], pos[N << ], cnt[N << ];
struct node
{
int lazy, Min, pos, cnt;
node () {}
node (int lazy, int Min, int pos, int cnt) : lazy(lazy), Min(Min), pos(pos), cnt(cnt) {}
void init() { lazy = ; Min = INF; pos = ; cnt = ; }
node operator + (const node &r) const
{
node res = node(, INF, , );
res.cnt = cnt + r.cnt;
if (Min < r.Min)
{
res.Min = Min;
res.pos = pos;
}
else
{
res.Min = r.Min;
res.pos = r.pos;
}
return res;
}
}a[N << ], res;
void build(int id, int l, int r)
{
a[id] = node(, INF, , );
if (l == r)
{
a[id] = node(, k, l, );
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
a[id] = a[id << ] + a[id << | ];
}
void change(int id, int lazy)
{
a[id].lazy += lazy;
a[id].Min += lazy;
}
void pushdown(int id)
{
if (!a[id].lazy) return;
change(id << , a[id].lazy);
change(id << | , a[id].lazy);
a[id].lazy = ;
}
void update(int id, int l, int r, int ql, int qr, int val)
{
if (l >= ql && r <= qr)
{
a[id].Min += val;
a[id].lazy += val;
return;
}
pushdown(id);
int mid = (l + r) >> ;
if (ql <= mid) update(id << , l, mid, ql, qr, val);
if (qr > mid) update(id << | , mid + , r, ql, qr, val);
a[id] = a[id << ] + a[id << | ];
}
void update(int id, int l, int r, int pos)
{
if (l == r)
{
a[id].Min = INF;
a[id].cnt = ;
return;
}
pushdown(id);
int mid = (l + r) >> ;
if (pos <= mid) update(id << , l, mid, pos);
else update(id << | , mid + , r, pos);
a[id] = a[id << ] + a[id << | ];
}
void query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr)
{
res = res + a[id];
return;
}
pushdown(id);
int mid = (l + r) >> ;
if (ql <= mid) query(id << , l, mid, ql, qr);
if (qr > mid) query(id << | , mid + , r, ql, qr);
a[id] = a[id << ] + a[id << | ];
}
}seg; int main()
{
while (scanf("%d%d%d", &n, &k, &m) != EOF)
{
for (int i = ; i <= m; ++i) que[i].scan();
sort(que + , que + + m);
seg.build(, , n);
ll res = ;
for (int i = , l, r, c, p; i <= m; ++i)
{
l = que[i].l, r = que[i].r, c = que[i].c, p = que[i].p;
while ()
{
seg.res.init();
seg.query(, , n, l, r);
if (seg.res.cnt == ) break;
if (seg.res.Min <= c)
{
res += (ll)p * seg.res.Min;
seg.update(, , n, seg.res.pos);
}
else
{
res += (ll)p * seg.res.cnt * c;
seg.update(, , n, l, r, -c);
break;
}
}
}
printf("%lld\n", res);
}
return ;
}

D. Garbage Disposal

水。

 #include<bits/stdc++.h>

 using namespace std;

 typedef long long ll;

 int main()
{
ll n, k;
while(~scanf("%lld %lld", &n, &k))
{
ll ans = ;
ll res = ;
for(int i = ; i <= n; ++i)
{
ll x;
scanf("%lld", &x);
if(res > )
{
res += x;
if(res >= k)
{
ans += res / k;
res %= k;
}
else
{
res = ;
ans++;
}
}
else
{
res += x;
ans += res / k;
res %= k;
}
}
if(res)
{
ans += res % k == ? res / k : res / k + ;
}
printf("%lld\n", ans);
}
return ;
}

E. Getting Deals Done

Solved By 2017212212083 & Dup4

题意:

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

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

思路:

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

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 200010
int t, n, m; ll T;
int p[N], b[N]; bool check(int x)
{
int dd = p[x];
ll tmp = , TT = T; int cnt = , tot = ;
for (int i = ; i <= n; ++i) if (b[i] <= dd)
{
if (TT - b[i] >= )
{
++cnt; TT -= b[i];
tmp += b[i];
++tot;
}
else return tot >= x;
if (cnt == m)
{
cnt = ;
TT -= tmp;
tmp = ;
}
}
if (tot >= x)
{
return true;
}
return false;
} int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d%d%lld", &n, &m, &T);
for (int i = ; i <= n; ++i) scanf("%d", p + i), b[i] = p[i];
sort(p + , p + + n);
p[] = T;
int l = , r = n, res = -;
while (r - l >= )
{
int mid = (l + r) >> ;
if (check(mid))
{
res = mid;
l = mid + ;
}
else
r = mid - ;
}
printf("%d %d\n", res, p[res]);
}
return ;
}

F. Debate

水。

 #include <bits/stdc++.h>
using namespace std; #define N 400010
int n, a[N], cnt[];
priority_queue <int> pq[]; void init()
{
memset(cnt, , sizeof cnt);
for (int i = ; i < ; ++i) while (!pq[i].empty()) pq[i].pop();
} int main()
{
while (scanf("%d", &n) != EOF)
{
init(); int res = ;
for (int i = , x; i <= n; ++i)
{
scanf("%02d%d", &x, a + i);
if (x == ) x = ;
else if (x == ) x = ;
++cnt[x];
if (x == ) res += a[i];
else pq[x].push(a[i]);
}
int limit = min(cnt[], cnt[]);
for (int i = ; i <= ; ++i) for (int j = ; j < limit; ++j)
{
res += pq[i].top(); pq[i].pop();
}
for (int i = ; i <= ; ++i) while (!pq[i].empty())
{
pq[].push(pq[i].top()); pq[i].pop();
}
limit = min(cnt[], (int)pq[].size());
for (int i = ; i < limit; ++i)
{
res += pq[].top(); pq[].pop();
}
printf("%d\n", res);
}
return ;
}

G. Monsters and Potions

Unsolved.

H. BerOS File Suggestion

水。

 #include<bits/stdc++.h>

 using namespace std;

 map<string, int>mp1;
map<string, string>mp2; int n, q;
string s; int main()
{
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
while(cin >> n)
{
mp1.clear();
mp2.clear();
for(int i = ; i <= n; ++i)
{
cin >> s;
int len = s.length();
set<string>st;
for(int i = ; i < len; ++i)
{
string tmp = "";
for(int j = i; j < len; ++j)
{
tmp += s[j];
st.insert(tmp);
}
}
for(auto it : st)
{
mp1[it]++;
mp2[it] = s;
}
}
cin >> q;
while(q--)
{
cin >> s;
cout << mp1[s] << " ";
if(mp1[s])
{
cout << mp2[s] << "\n";
}
else
{
cout << "-\n";
}
}
}
return ;
}

I. Privatization of Roads in Berland

Unsolved.

J. Streets and Avenues in Berhattan

Unsolved.

K. Video Posts

水。

 #include<bits/stdc++.h>

 using namespace std;

 const int maxn = 1e5 + ;

 int n, k;
int arr[maxn];
int sum; void solve()
{
if(sum % k)
{
puts("No");
return ;
}
vector<int>vec;
int res = ;
int st = ;
for(int i = ; i <= n; ++i)
{
res += arr[i];
if(res > sum / k)
{
puts("No");
return ;
}
else if(res == sum / k)
{
vec.push_back(i - st);
st = i;
res = ;
}
}
puts("Yes");
for(int i = , len = vec.size(); i < len; ++i)
{
printf("%d%c", vec[i], " \n"[i == len - ]);
}
} int main()
{
while(~scanf("%d %d", &n ,&k))
{
sum = ;
for(int i = ; i <= n; ++i)
{
scanf("%d", arr + i);
sum += arr[i];
}
solve();
}
return ;
}

L. Odd Federalization

Unsolved.

M. Algoland and Berland

Unsolved.

2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) Solution的相关教程结束。

《2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) Solution.doc》

下载本文的Word格式文档,以方便收藏与打印。