1 solutions

  • 1
    @ 2021-10-25 23:20:27

    考点

    二进制、位运算,模拟

    题意

    给你一个数字X,然后我们在它的二进制下可以进行两个操作:

    • 如果X当前在二进制下有偶数个1那么我们将最低位上的值和1进行异或操作
    • 如果X当前在二进制下有奇数个1那么我们将最高位上的值和1进行异或操作

    至少通过多少次操作能让X变为0

    思路

    直接暴力模拟即可,因为数据才1e10,也就是最多33位,我们可以直接用二进制的左移来枚举,当然也可以先将这个数转化成二进制存在数组里面,然后再逐步操作

    CODE

    #include<bits/stdc++.h>
    #include<cstdlib>
    using namespace std;
    
    #define ll long long
    ll n,t;
    
    ll slove(ll k) {
    	ll ans = 0;
    	ll kk = 0;
    	for(ll j = 0;j < 34; ++j) {//计算1的个数
    		if(k &(1LL<<j)) kk++;
    	}
    	if(kk&1) {//如果有奇数个我们先处理一次,然后1的个数就会变成偶数个
    		for(ll j = 34;j >= 0; --j)//找到最高位
    			if(k & (1LL<<j) )  {
    				k -= (1LL<<j);
    				ans++;
    				break;
    			}
    	}
    	for(ll i = 34LL;i >= 0; --i) {//逐步模拟
    		if(k & (1LL<<i)) {//如果当前位置为1那么我们就进行操作
    			if(k & 1) k--;//如果低位为1的话那么我们就先让k的值-1  =》 1 xor 1 = 1
    			else k++;//如果低位为0的话那么我们就先让k的值+1  =》 1 xor 0 = 0
    			ans++;
    			if(k == 0) break;//如果为0跳出
    			
    			k -= (1LL<<i);//处理高位情况
    			ans++;
    			if(k == 0) break;//如果为0跳出
    		}
    	}
    	return ans;//返回操作次数
    }
    
    int main()
    {
    	scanf("%lld",&t);
    	while(t--) {
    		scanf("%lld",&n);
    		printf("%lld\n",slove(n));
    	}
    	return 0;
    }
    
    • 1

    Information

    ID
    134
    Time
    2000ms
    Memory
    256MiB
    Difficulty
    8
    Tags
    # Submissions
    110
    Accepted
    13
    Uploaded By