1918(922div2)
A. Brick Wall
void solve()
{
int n, m;
cin >> n >> m;
m /= 2;
cout << n * m << '\n';
}
B. Minimize Inversions
给出
- 同时交换排列
位置,即 swap(a[i],a[j]),swap(b[i],b[j];
要使这两个排列的逆序对最少,输出
void solve()
{
int n;
cin >> n;
vector<pair<int, int>> f(n + 1);
for (int i = 1; i <= n; i++) cin >> f[i].first;
for (int i = 1; i <= n; i++) cin >> f[i].second;
sort(f.begin() + 1, f.begin() + 1 + n);
for (int i = 1; i <= n; i++) cout << f[i].first << " ";
cout << '\n';
for (int i = 1; i <= n; i++) cout << f[i].second << " ";
cout << '\n';
}
C. XOR-distance
Solution
贪心
官方题解:
我们来考虑数字
-
如果它们相同,那么无论
在该位置上是什么,数字 在这个位置上都会是 0。因此,在所有这样的位置上设置为 0 是有利的(因为我们希望 ,并且答案不取决于位)。 -
如果
和 在同一位置的位不同,则在该位置上,无论是在 还是在 中都会有一个1,取决于 在该位置上是什么。
假设
位不同则有
- 要么在这个位置上在
中设置一个 1(然后在该位 ) - 要么在
中设置一个 0(然后在该位 )。
假设我们在
因此,我们可以按降序遍历位置,如果位置不同,则在该位置上设置一个 1 在
第二种情况(当我们在第一个不同的位上设置 1)类似地进行分析,但实际上并不需要,因为答案不会更小,而
时间复杂度:每个测试用例
代码
我一开始没有看懂为什么后面直接答案输出
#define int long long
void solve()
{
int a, b, r, x = 0;
cin >> a >> b >> r;
if (a > b)
swap(a, b);
bool cn = 1;
for (int i = 60; i >= 0; i--)
{
if ((a & (1LL << i)) != (b & (1LL << i)))//同一位置的位不同
{
if (cn)//第一个最高位不同的位置
cn = 0;
else
{
if (!(a & (1LL << i)) && x + (1LL << i) <= r)
{
x += (1ll << i);//x在该位为1
a ^= (1ll << i);
b ^= (1ll << i);
}
}
}
}
cout << b - a << '\n';
}
搞了半天和我的想法是一样的,最终的答案就是
假设我们在
中设置一个 0,那么 肯定会小于 (因为在最高位不同的情况下一定有: )。因此,有利的是在所有接下来的位置上,在 中设置一个 1,因为这将使它们的差值更小。
#define int long long
void solve()
{
int a, b, r, x = 0;
cin >> a >> b >> r;
if (a > b)
swap(a, b);
bool cn = 1;
for (int i = 60; i >= 0; i--)
{
if ((a & (1LL << i)) != (b & (1LL << i)))
{
if (cn)
cn = 0;
else
{
if (!(a & (1LL << i)) && x + (1LL << i) <= r)
x += (1ll << i);
}
}
}
cout << (b ^ x) - (a ^ x) << '\n';
}
D. Blocking Elements
(待更