CCPC2018桂林D. Bits Reverse —— 思维 + 贪心

第一签到题

题意:

T组输入,每组输入包含两个数字x和y(long long int)。对x有一种操作,可以将 x的二进制 任意相邻的三个位逆置。

问最少进行多少次操作,可以使得x等于y,不可能则输出-1

思路:

reverse三个位置,即中间位置不受影响,即奇数位置和偶数位置1的数量是固定的,所以先判断x y奇数偶数位置的1数量是否分别相等,不等则不可能,否则一定可以达到。

然后考虑最小化次数,首先分成奇偶两部分,对每一部分,贪心的枚举每个1的位置,然后对应位置相减取abs即可, 具体见代码。

// Decline is inevitable,
// Romance will last forever.
#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pii pair<int,int>
#define pb push_back
#define fi first
#define se second
#define ll long long
#define LL long long
#define int long long
#define endl '\n'
const int maxn = 1e5 + 10;
const int maxm = 1e3 + 10;
const int INF = 0x3f3f3f3f;
//const int dx[] = {0, 0, -1, 1}; //{0, 0, 1, 1, 1,-1,-1,-1}
//const int dy[] = {1, -1, 0, 0}; //{1,-1, 1, 0,-1, 1, 0,-1}
const int P = 998244353;
int n;
int t = 0;
void solve() {
    int x, y;
    cin >> x >> y;
    int cnt1 = 0, cnt2 = 0;
    int cnt3 = 0, cnt4 = 0;
    vector<int> v1, v2, v3, v4;
    for(int i = 0; i <= 63; i++) {
        if((x >> i) & 1) {
            if((i+1) & 1) cnt1++, v1.pb(i+1);
            else
                cnt2++, v2.pb(i+1);
        }
        if((y >> i) & 1) {
            if((i+1) & 1) cnt3++, v3.pb(i+1);
            else cnt4++, v4.pb(i+1);
        }
    }
    if(cnt1 != cnt3 || cnt2 != cnt4) {
        cout << -1 << '\n';
        return;
    }
    int ans = 0;
    for(int i = 0; i< cnt1; i++)   ans += abs(v1[i] - v3[i]);
    for(int i = 0; i < cnt2; i++) ans += abs(v2[i] - v4[i]);
    ans >>= 1;
    cout << ans << '\n';
    
    

}
signed main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int T; cin >> T; while(T--) {
        cout << "Case " << ++t << ": ";
        solve();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_59273843/article/details/121071794