Codeforces Round 1095 (Div. 2)补题
A. Disturbing Distribution
知识点:思维
思路:很容易发现如果 \(a,b !=1\) ,则有\(a*b>=a+b\),所以最小的代价应该是将所有不为 \(1\) 的数加起来,对于数值为 \(1\) 的数,如果他后面有大于 \(1\) 的数,可以一同被带走,但如果没有,就需要额外判断一下,也就是判断最末尾的元素是否为 \(1\) 即可
B. Everything Everywhere
知识点:数论,思维
思路:拿一个符合题中条件的序列来讲,每个数都可以整除 \(gcd\),所以这个序列中每个序列的差的绝对值也可以整除 \(gcd\),所以如果一个数大于另一个数,他们的差一定是 \(gcd\) 的整数倍,已知 \(max-min=gcd\),所以这个序列中只有两个元素,也就是我们只需要检查相邻的就可以了
C. Mental Monumental (Easy Version)
知识点:二分
思路:二分 \(mex\),如果 \(a_i\) 比 \(mid\) 小的话就可以直接设 \(b_i\) 为一个很大的值,使得 \(a_i\) 不变,如果 \(a_i\) 比 \(mid\) 大的话,通过 \(mod\) 转化为一个小的数,对于比 \(mid\) 大的数,这个数一定是越大越好,为什么呢 ?因为如果进行转化的话,一定有 \(a_i>2*c_i\),如果 \(b_i<=x/2\),\(a_i%b_i<b_i,所以c_i<=x/2\),如果 \(b_i>x/2\),\(a_i%b_i<x/2,所以c_i<=x/2\),综上,找出较大的数,找出不满足的数,比较大小,如果较大的数少就不满足条件
Code
点击查看代码
bool check(int mid, const vi &a)
{
if (mid == 0)
return 1;
vb vis(mid, 0);
for (int x : a)
{
if (x < mid)
{
vis[x] = 1;
}
}
vi b;
b.reserve(mid);
for (int i = 0; i < mid; i++)
{
if (!vis[i])
{
b.pb(i);
}
}
int len = b.size();
if (len == 0)
return 1;
vi c;
c.reserve(len);
vb v(mid, 0);
for (int i = n - 1; i >= 0 && c.size() < len; i--)
{
int now = a[i];
if (now < mid && !v[now])
{
v[now] = 1;
}
else
{
c.pb(now);
}
}
if (c.size() < len)
return 0;
for (int i = 0; i < len; i++)
{
if (c[len - 1 - i] < 2 * b[i] + 1)
{
return 0;
}
}
return 1;
}
void solve()
{
cin >> n;
vi a(n);
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
sort(all(a));
l = 0, r = n;
int res = 0;
while (l <= r)
{
int mid = l + ((r - l) >> 1);
if (check(mid, a))
{
res = mid;
l = mid + 1;
}
else
{
r = mid - 1;
}
}
cout << res << endl;
}
D. Reserved Reversals
知识点:思维
思路:如果天然有序直接输出。手模发现,我们可以让奇数在一边,偶数在一边,如果我们能对奇偶数内部分别排好序,那么整个序列就排好序了,拿奇数来说,如果存在逆序对,我们需要一个偶数来帮他们来转换,所以如果天然乱序且只有偶数或只有奇数的情况直接否定,这个偶数有两种选择,比这两个奇数都大或都小,如果有这样的偶数,就可以转换,如果没有就不可以转换。按照这个思路我们需要找出奇数和偶数中所有的逆序对,最坏情况是 \(O(n^2)\) 的,时间复杂度太高。再考虑如果存在一个奇数比最大的偶数大,一个奇数比最小的偶数小,并且他们是逆序对,这种情况直接否定,偶数也这样处理,如果没有这种情况就是可以使得数组有序的。找到最左边且大于最大偶数的奇数,同时找到最右边且小于最小偶数的奇数,判断他们的位置是否为逆序对,对于偶数也这样操作,验证这两种情况,存在一种就为否,都不存在就为 \(YES\)
Code
点击查看代码
void solve()
{
cin >> n;
vi a(n);
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
if (is_sorted(all(a)))
{
cout << "YES" << endl;
return;
}
int mxji = -1, miji = 1e9, mxou = -1, miou = 1e9;
int ji = 0, ou = 0;
for (int x : a)
{
if (x & 1)
{
mxji = max(mxji, x);
miji = min(miji, x);
ji = 1;
}
else
{
mxou = max(mxou, x);
miou = min(miou, x);
ou = 1;
}
}
if (ji && ou)
{
}
else
{
cout << "NO" << endl;
return;
}
int ok = 0;
int da = -1, xiao = -1;
for (int i = 0; i < n; i++)
{
if (!ok && da == -1 && a[i] % 2 == 0 && a[i] > mxji)
{
da = i;
}
if (a[i] % 2 == 0 && a[i] < miji)
{
xiao = i;
}
}
if (xiao > da && xiao != -1 && da != -1)
{
cout << "NO" << endl;
return;
}
ok = 0;
da = -1, xiao = -1;
for (int i = 0; i < n; i++)
{
if (!ok && da == -1 && a[i] % 2 != 0 && a[i] > mxou)
{
da = i;
}
if (a[i] % 2 != 0 && a[i] < miou)
{
xiao = i;
}
}
if (xiao > da && xiao != -1 && da != -1)
{
cout << "NO" << endl;
return;
}
cout << "YES" << endl;
}

浙公网安备 33010602011771号