Codeforces Round 922 (Div. 2)

本文介绍了CodeforcesRound922(Div.2)中三个问题的解题方法:A.BrickWall使用模拟和贪心策略填充砖块,B.MinimizeInversions通过排序消除逆序对,C.XOR-distance利用位运算解决异或距离问题。
摘要由CSDN通过智能技术生成

Codeforces Round 922 (Div. 2)

A. Brick Wall

模拟、贪心

不需要竖着的砖块,全部为横着的砖块即可。

如果发现一行填不满,只需要将一个位置换成 1x3的砖块即可

其余的都填1x2的砖块

#include<bits/stdc++.h>

typedef long long ll;
using namespace std;

int main(){
    int t;
    cin>>t;
    while(t--){
        int n,m;
        cin>>n>>m;
        ll ans=0;
        if(m&1){
            m-=3;
            ans+=n;
        }
        ans+= n*(m/2);
        cout<<ans<<endl;
    }
}

B.Minimize Inversions

思维,模拟

每次选中两个下标,进行交换。一共有三种情况。

1、选中的下标里有一对逆序对,那么交换后,仍然是一对

2、选中的下标里有两对逆序对,交换后变成0对

3、选择的下标里有0对逆序对,交换后变成2对

只要我们把一个数组排好序,那么不管怎么交换,都不会减少逆序对的数量。

#include<bits/stdc++.h>
   
using namespace std;
#define  ios ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr) 


const int N = 1e6 + 7;
typedef long long ll;

class arr {
public:
    int a, b;
};

bool cmp(arr v, arr t) {
    return v.a < t.a;
}
int main() {
   
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        vector<arr> v(n);
        for (int i = 0; i < n; i++)cin >> v[i].a;
        for (int i = 0; i < n; i++)cin >> v[i].b;

        sort(v.begin(), v.end(), cmp);

        for (auto c : v)cout << c.a << ' ';
        cout << endl;
        for (auto c : v)cout << c.b << ' ';
        cout << endl;

    }
    
}

C.XOR-distance

二进制,位运算,贪心

思路:

异或是相同为0,不同为1

二进制有这样一个规律:

第x位为1大于 0~x-1 的所有位为1的值

a=916721749674600979 

​ 110010111000110110011001001100000111001110101010101000010011

     b=735268590557942972 

101000110100001100101110001100110010101101010101010010111100

找到a中第一个与b不同的位,且a在这位上是1.

让x在这位上必须为0.

此后,所有的a与b不同的位,x都与a相同即可

#include<iostream>
#include<fstream>
#include<string>
#include<algorithm>
#include<map>
#include<vector>
#include<set>
#include<stack>
using namespace std;
#define  ios ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr) 
#define lson pos<<1
#define rson (pos<<1)|1

const int N = 1e6 + 7;
typedef long long ll;


int main() {
    ios;
    int t;
    cin >> t;
    while (t--) {
        ll a, b, r;
        cin >> a >> b >> r;
        if (a < b)swap(a, b); //始终保证a>b

        vector<ll> v1, v2;
        ll t1 = a, t2 = b;

        while (t1) {
            v1.push_back(t1 % 2);
            t1 /= 2;
        }

        while (t2) {
            v2.push_back(t2 % 2);
            t2 /= 2;
        }
        
        v2.resize(v1.size());
        ll x = 0;
        bool is_yes = 0;
        
        for (int i = v1.size() - 1; i >= 0; i--) {
            if (v1[i] != v2[i]) {
                if (v1[i] == 1) {
                    if (is_yes == 0) { //第一次不同时,x的第i位为0
                        is_yes = 1;
                        continue;
                    }
                    else {//后续v1,v2只要有一位不同,那x就尽可能与v1的该位相同
                        if (x + (1ll << i) <= r) {
                            x = x + (1ll << i);
                        }
                    }
                }
            }
        }
        a = a ^ x;
        b = b ^ x;
        if (a < b)swap(a, b);
        cout << a - b << endl;
    }
}

   }
                }
            }
        }
    }
    a = a ^ x;
    b = b ^ x;
    if (a < b)swap(a, b);
    cout << a - b << endl;
}

}










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

louisdlee.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值