
Codeforces Round 892 (Div. 2) 赛后总结
小菜鸡的赛后总结

A. United We Stand
- 题意:给出一个长度为n的包含整数的数组a,有两个空数组b和c,你需要不断将a中的元素移到b或者c中,保证最后b和c都为非空,且c中任意一个元素都不是b中任意一个元素的因数
- 思路:排序一遍,直接把最小的数加入b中,最大的数加入c中
void BlueFire()
{
int n;
cin >> n;
vector<int> v(n + 1);
for (int i = 1; i <= n; i++)
cin >> v[i];
sort(v.begin(), v.end());
vector<int> b;
vector<int> c;
for (int i = 1; i <= n; i++)
{
if (i == 1)
{
b.push_back(v[i]);
continue;
}
if (v[i] == v[1])
{
b.push_back(v[i]);
continue;
}
c.push_back(v[i]);
}
if (b.size() == 0 || c.size() == 0)
{
cout << -1 << endl;
return;
}
else
{
cout << b.size() << " " << c.size() << endl;
for (auto x : b)
cout << x << " ";
cout << endl;
for (auto x : c)
cout << x << " ";
cout << endl;
}
return;
}
B. Olya and Game with Arrays
- 题意:给出n个数组,可以执行一次操作:对于这n个数组,从每个数组中选取一个数,将这n个数转移到其他数组中,求出执行操作后,每个数组最小值之和的最大值
- 思路:首先容易想到每次选取的就是最小值,为了让其他数组的最小值变大,考虑把所有的最小值都扔到一个数组上,那么这个数组是哪一个呢,这取决于每个数组中第二大的数字,第二大的数字最小的那个数组就是要转移的数组
void BlueFire()
{
int n;
cin >> n;
vector<PII> v;
int fmins = 1e9 + 1;
for (int i = 1; i <= n; i++)
{
int l;
cin >> l;
vector<int> ts(l);
for (int j = 0; j < l; j++)
cin >> ts[j];
sort(ts.begin(), ts.end());
int x = ts[1], y = ts[0];
v.emplace_back(x, y);
fmins = min(fmins, y);
}
sort(v.begin(), v.end());
ll ans = fmins;
for (int i = 1; i < v.size(); i++)
ans += v[i].first;
cout << ans << endl;
return;
}
D. Andrey and Escape from Capygrad
- 题意:给出线段上的许多区间,当处于[l,r]上,便可以传送到[a,b]上的任意一点,其中l<=a<=b<=r,有许多这样的区间,给出起始位置,求出最远能到哪个点
- 思路:首先对于单个区间,如果当前位置在l到b,那么一定会选择传送到b,如果在b之后无法传送,所以每个区间其实只需要关注[l,b]即可,然后进行合并区间,最后二分寻找离起始点最近的左端点
void BlueFire()
{
int n;
cin >> n;
vector<pll> e(n + 1);
for (int i = 1; i <= n; i++)
{
int li, r, a, b;
cin >> li >> r >> a >> b;
e[i] = {li, b};
}
sort(e.begin() + 1, e.end());
vector<pll> fe;
for (int i = 1; i <= n;)
{
int j = i + 1;
int x = e[i].first, y = e[i].second;
while (j <= n && e[j].first <= y)
{
y = max(e[j].second, y);
j++;
}
fe.emplace_back(x, y);
i = j;
}
int q;
cin >> q;
while (q--)
{
int x;
cin >> x;
int l = 0, r = fe.size() - 1;
while (l < r)
{
int mid = (l + r + 1) >> 1;
if (fe[mid].first <= x)
l = mid;
else
r = mid - 1;
}
if (fe[l].first <= x && fe[l].second >= x)
cout << fe[l].second << " ";
else
cout << x << " ";
}
cout << endl;
return;
}