(5/6) Educational Codeforces Round 100 (Div. 2)
A. Dungeon
题意:
三个数a,b,c代表三个怪物的血量,有一门炮,每次发射会对一个怪物造成伤害1,当发射的次数为7的倍数时,会对三个怪物同时造成1的伤害,要求是否可以在最后一次发射时同时杀死三个怪物。
思路:
求和如果不能被9整除,则输出no。
每一轮会对和减9,最少对每只怪物造成伤害1,所以记录9的次数t,如果存在怪物的初始值小于t,那么输出no。
否则输出yes。
代码:
#include <bits/stdc++.h>
using namespace std;
void work() {
int a, b, c;
cin >> a >> b >> c;
int sum = a + b + c;
int cnt = 0, flag = false;
cnt = sum / 9, sum %= 9;
if (sum == 0) flag = true;
if (!flag) puts("NO");
else {
if (a < cnt || b < cnt || c < cnt) puts("NO");
else puts("YES");
}
}
int main() {
int t;
cin >> t;
while (t--) work();
}
B. Find The Array
题意:
给定一个数组A,要求构造一个数组B,数组B满足:
相邻的两个元素i,j:要求i被j整除或者j被i整除。
元素的值在1——1e9之间。
A与B数组每个对应元素的差的绝对值之和小于A数组元素之和除以2。
思路:
对于A中的每个元素i:枚举2的x次方,找到其第一次大于i时对应的x,B中对应位置存放2的x-1次方。
证明:
相邻两个数都为2的次方,可以互相整除。
2的x次方大于i,则2的x-1次方小于i,因此数组B中每个元素都小于等于数组A中对应元素的值,因此数组B中元素的值都在1到1e9之间。
2的x次方大于i,2的x-1次方大于i/2,因此B元素对应的值大于i/2,因此其与A对应元素的绝对值只差小于i/2。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
using pii = pair<int, int>;
long long sum = 0;
int a[60];
int b[60];
void work() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
b[i] = a[i];
}
for (int i = 0; i < n; i++) {
int w = 1;
for (int j = 0; j < 32; j++) {
if ((w << j) > a[i]) {
a[i] = (w << (j - 1));
break;
}
}
}
for (int i = 0; i < n; i++) cout << a[i] << " "; cout << endl;
}
int32_t main() {
int t;
cin >> t;
while (t--) work();
}
C. Busy Robot
题意:
给出一个数n,代表有n条命令,初始位置在0号点。
每条命令有两个值x,y,x代表时间,y代表目标。
初始时机器人接到命令立刻向目标点出发,在下个命令前如果到达目标点,则到达之后且在下个命令的时间前静止;如果在下个命令发布时,未达到目标点,则会忽略下一个命令,如此类推。
如果机器人在命令i和命令i+1之间经过了i命令的目标点,则i为有效命令,求有效命令的个数。
思路:
模拟,结尾设一个标兵。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
using pii = pair<int, int>;
#define x first
#define y second
constexpr int maxn = 100010;
pii a[maxn];
void work() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i].x >> a[i].y;
a[++n] = {10e9, 100e9};
int ans = 0, pos = 1e9 + 10;
int l = 0, r = 0;
for (int i = 1; i + 1 <= n; i++) {
if (pos == 1e9 + 10) pos = a[i].y;
//cout << pos << "!!" << endl;
int time = a[i + 1].x - a[i].x;
int dis = time;
//cout << i << " " << dis << endl;
if (pos <= l) {
r = l - dis;
if (r <= pos) r = pos, pos = 1e9 + 10;
if (a[i].y >= min(l,r) && a[i].y <= max(l,r)) ans++;
l = r;
} else {
//cout << "!" << endl;
r = l + dis;
if (r >= pos) r = pos, pos = 1e9 + 10;
if (a[i].y >= min(l,r) && a[i].y <= max(l,r)) ans++;
l = r;
}
//cout << "-------" << l << endl;
//cout << ans << endl;
}
//if (pos == 1e9 + 10) ans++;
cout << ans << endl;
}
int32_t main() {
int t;
cin >> t;
while (t--) work();
}
D. Pairs
题意:
在一个1-2n的排列当中,我们可以把每两个组成一对,x对取最小值加入A中,n-x对取最大值加入A中。
现在给出A数组,问在1-2n的排列中,我们可以任意组合,一共可以选出几种x,使得其能组成数组A。
思路:
我们把在数组A中的值从小到大加入a中,未在数组A中的值从小到大加入数组b中。
我们确定x的取值范围l,r,那么r-l+1即为所求。
我们二分取x的最大值,也就是最多可以取多少个最小,二分的check函数为a中的前mid个元素是否比b中的后mid个元素小。
我们二分取y的最大值,也就是最多可以取多少个最大,二分的check函数为a中的后mid个元素是否比b中的前mid个元素大。y最大即为x最小,因此x的最小为n-y。
即答案为x-(n-y)+1。
代码:
#include <bits/stdc++.h>
using namespace std;
constexpr int maxn = 1e6;
bool st[maxn];
void work() {
int n;
cin >> n;
memset(st, 0, sizeof st);
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
st[x] = 1;
}
vector<int> a, b;
for (int i = 1; i <= 2 * n; i++)
if (st[i]) a.push_back(i);
else b.push_back(i);
int l = 0, r = n, R, L;
while (l < r) {
int mid = l + r + 1 >> 1;
bool ok = 1;
for (int i = 0; i < mid; i++) if (a[i] > b[n - mid + i]) ok = 0;
if (ok) l = mid;
else r = mid - 1;
}
R = l;
// cout << "---" << R << endl;
l = 0, r = n;
while (l < r) {
int mid = l + r + 1>> 1;
bool ok = 1;
for (int i = 0; i < mid; i++) if (b[i] > a[n - mid + i]) ok = 0;
if (ok) l = mid;
else r = mid - 1;
}
// cout << "!!!" << l << endl;
cout << R - (n - l) + 1 << endl;
}
int main() {
int cas;
cin >> cas;
while (cas--) work();
}
E. Plan of Lectures
题意:
做一次演讲,其中一些话题必须在一些话题之前演讲,并且有若干对话题x和y,在x演讲完之后必须紧接着演讲y,问演讲的顺序,不存在输出0,其中每对中的x与其他对的x不同,y也如此。
思路:
我们根据若干对的组合把所有点缩点,由于其一定为一条链或者单个的点,记录链中点的顺序,如果存在环则输出0跳出。
紧接着建图连边,如果两个点属于同一缩点的集合,检查顺序是否符合链的顺序,如果不在同一集合,则连边,再拓扑排序判环,存在环则输出0跳出。
接下来对拓扑排序的缩点集合依次输出每个点集的序列。
代码:
#include <bits/stdc++.h>
using namespace std;
int n, m;
constexpr int maxn = 300010;
int fa[maxn];
int ne[maxn];
int ind[maxn];
int order[maxn];
int cc;
int be[maxn];
vector<int> g[maxn];
vector<int> v[maxn];
void ex() {
cout << 0 << endl;
exit(0);
}
void topsort1() {
// for (int i = 1; i <= n; i++) cout << ind[i] << endl;
for (int i = 1; i <= n; i++) {
int tt = 0;
// cout << "!!!!" << ind[i] << " " << order[i]
if (!ind[i] && !order[i]) {
cc++;
// cout << i << endl;
for (int j = i; j; j = ne[j]) {
// cout << "---" << endl;
// cout << j << endl;
order[j] = ++tt;
be[j] = cc;
v[cc].push_back(j);
if (ne[j] == 0) break;
ind[ne[j]]--;
}
///for (int i = 1; i <= n; i++) cout << order[i] << endl;
//cout << "---" << endl;
///for (int i = 1; i <= n; i++) cout << ind[i] << endl;
}
}
for (int i = 1; i <= n; i++)
if (ind[i]) ex();
// for (int i = 1; i <= n; i++) cout << be[i] << endl;
// cout << "-------" << endl;
// cout << cc << endl;
}
void topsort2() {
for (int i = 1; i <= n; i++) {
// cout << be[i] << endl;
if (fa[i]) {
if (be[i] == be[fa[i]]) {
// cout << "!!" << endl;
if (order[fa[i]] > order[i]) ex();
} else {
g[be[fa[i]]].push_back(be[i]);
// cout << "---" << be[fa[i]] << endl;
ind[be[i]]++;
}
}
}
// cout << "-------" << endl;
queue<int> q;
for (int i = 1; i <= cc; i++)
if (ind[i] == 0) q.push(i);
//cout << "---" << q.front() << endl;
//cout << g[q.front()][0] << endl;
//cout << g[q.front()][1] << endl;
//cout << g[2].size() << endl;
vector<int> res;
while (q.size()) {
//cout << "!!!!!!!!!!!!!" << endl;
int u = q.front();
//cout << "---" << u << endl;
q.pop();
//cout << q.size() << endl;
res.push_back(u);
for (int i = 0; i < g[u].size(); i++) {
//cout << u << " " << "!" << endl;
//cout << g[u][i] << " " << ind[g[u][i]] << endl;
if (--ind[g[u][i]] == 0) {
q.push(g[u][i]);
//cout << "!!!" << endl;
//cout << g[u][i] << endl;
}
// cout << g[u][i] << endl;
}
}
//cout << res.size() << endl;
// for (int i = 0; i < res.size(); i++) cout << res[i] << endl;
if (res.size() != cc) ex();
// cout << "-------" << endl;
for (auto i : res)
for (auto j : v[i])
cout << j << " ";
cout << endl;
}
int main() {
cin.tie(0);
cout.tie(0);
ios_base::sync_with_stdio(false);
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> fa[i];
for (int i = 1; i <= m; i++) {
int x, y;
cin >> x >> y;
ne[x] = y;
ind[y]++;
}
topsort1();
topsort2();
}