Codeforces Round 922 (Div
\(\Huge{Codeforces Round 922 (Div. 2)}\)
Problems A. Brick Wall
思路
给定一个大小为\(n\times m\)的墙,并给出无限个大小为\(1\times x(2\le x)\)的砖,要求刚好将墙铺满,若砖横着放,则稳定性\(+1\),否则\(-1\),求最大稳定性。
若令稳定性最大,我们考虑全部用大小为的砖,采用横铺,若每排不能刚好铺满,则最后一块砖就选长一点即可。
标程
void Solved() {
int n, m; cin >> n >> m;
cout << m / 2 * n << endl;
}
Problems B. Minimize Inversions
思路
给出两个长度为n的数组,要求同时对两数组操作,每次操作选中两个下标,并进行交换。要求操作后的两数组中逆序对最少,并输出操作后的两数组。
要令两数组的逆序数最少,只需将其中一个数组变为升序,即一个数组中逆序数个数为零,则两数组的逆序对个数就是最少。
标程
void Solved() {
int n; cin >> n;
vector<PII> a(n), b(n);
for(auto &i : a) cin >> i.fi;
for(auto &i : a) cin >> i.se;
sort(ALL(a));
for(int i = 0; i < n; i ++ ) {
cout << a[i].fi << " \n"[i == n - 1];
}
for(int i = 0; i < n; i ++ ) {
cout << a[i].se << " \n"[i == n - 1];
}
}
Problems C. XOR-distance
思路
给出三个整数\(a,b,r(0\le a,b,r\le 10^{18})\),求所有\(0\le x \le r\)中\(|(a\ xor\ x) - (b\ xor\ x)|\)的最小值。
数比较大,暴力显然不可能。
通过进行二进制拆分,可以近似得到\((a-b) = 2^{a_1} + 2^{a_2} + 2^{a_i}-2^{b_1}-2^{b_2}-2^{b_j}\)这样的形式。
对于上面的形式,若令\(|a-b|\)最小,需要将较大数\(a\)的最高位不变,其余\(b\)中没有的位给变为负即可。
通过观察题目所求,根据异或的性质(同为零,异为一)。对于所求值,我们可以将\(x\)视作将\(a\ or \ b\)的二进制下的某些位置取反,以达到取反后差值最小。
根据这一规律,我们判断\(a,b\)的相同位,从高位开始,较大数为\(1\)且较小数为\(0\)的位取反(即异或),但需要注意,较数的最高位应保持不变。经过这样操作后的两数差值会达到最小。
然后按位进行判断,并用x进行保存\((x<r)\)即可。
标程
void Solved() {
LL a, b, r; cin >> a >> b >> r;
if(a < b) swap(a, b);
LL cur = 0;
int t = 0;
for(int i = 60; i >= 0; i -- ) {
int x = a >> i & 1;
int y = b >> i & 1;
if(x <= y) continue;
if(!t) t = 1;
else if(cur + (1ll << i) <= r) cur |= 1ll << i;
}
cout << abs((a ^ cur) - (b ^ cur)) << endl;
}

浙公网安备 33010602011771号