C. Johnny and Another Rating Drop(codeforces)

C. Johnny and Another Rating Drop
问题:给出一个数n,求从0到n相邻两个数二进制不同位数的总和。
例如 1 = ( 01 ) 2 , 2 = ( 10 ) 2 1=(01)_2,2=(10)_2 1=(01)22=(10)2不同位数就为2。

我们列举一下找找规律:
0 = 0000 0=0000 0=0000
1 = 0001 1=0001 1=0001
2 = 0010 2=0010 2=0010
3 = 0011 3=0011 3=0011
4 = 0100 4=0100 4=0100
5 = 0101 5=0101 5=0101
6 = 0110 6=0110 6=0110
7 = 0111 7=0111 7=0111
数字每加1次,最低位改变,每加2次,次低位改变,每加4次,倒数第三位改变……

我们对n每次除2,求各个位数改变次数,求得最终答案。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll come(ll x) {
    
    
	ll ans = 0;
	while(x) {
    
    
		ans += x;
		x >>= 1;//每次除2
	}
	return ans;
}
int main() {
    
    
	ll t, n;
	scanf("%lld", &t);
	while(t--) {
    
    
		scanf("%lld", &n);
		printf("%lld", come(n)); 
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45363113/article/details/106796955