Codeforces Round 922 (Div. 2)(ABC)

C o d e f o r c e s R o u n d 922 ( D i v . 2 ) \Huge{Codeforces Round 922 (Div. 2)} CodeforcesRound922(Div.2)

文章目录

  • Problems A. Brick Wall
    • 思路
    • 标程
  • Problems B. Minimize Inversions
    • 思路
    • 标程
  • Problems C. XOR-distance
    • 思路
    • 标程

Problems A. Brick Wall

思路

给定一个大小为 n × m n\times m n×m的墙,并给出无限个大小为 1 × x ( 2 ≤ x ) 1\times x(2\le x) 1×x(2x)的砖,要求刚好将墙铺满,若砖横着放,则稳定性 + 1 +1 +1,否则 − 1 -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 ≤ a , b , r ≤ 1 0 18 ) a,b,r(0\le a,b,r\le 10^{18}) a,b,r(0a,b,r1018),求所有 0 ≤ x ≤ r 0\le x \le r 0xr ∣ ( a   x o r   x ) − ( b   x o r   x ) ∣ |(a\ xor\ x) - (b\ xor\ x)| (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) = 2^{a_1} + 2^{a_2} + 2^{a_i}-2^{b_1}-2^{b_2}-2^{b_j} (ab)=2a1+2a2+2ai2b12b22bj这样的形式。

对于上面的形式,若令 ∣ a − b ∣ |a-b| ab最小,需要将较大数 a a a的最高位不变,其余 b b b中没有的位给变为负即可。

通过观察题目所求,根据异或的性质(同为零,异为一)。对于所求值,我们可以将 x x x视作将== a   o r   b a\ or \ b a or b==的二进制下的某些位置取反,以达到取反后差值最小。

根据这一规律,我们判断 a , b a,b a,b的相同位,从高位开始,较大数为 1 1 1且较小数为 0 0 0的位取反(即异或),但需要注意,较数的最高位应保持不变。经过这样操作后的两数差值会达到最小。

然后按位进行判断,并用x进行保存 ( x < r ) (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;
}

你可能感兴趣的:(codeforces,c++,算法)