給定正整數 n,找出大於 n 的最小整數,使其二進制中 1 的個數相同。例如 78 (1001110, 四個 1) → 83 (1010011, 四個 1)。
從 n+1 開始逐個檢查,統計 1 的個數,相等即輸出。雖然簡單但對大數效率低。
int countOnes(int x) {
int c = 0;
while(x) { c += x & 1; x >>= 1; }
return c;
}
int main() {
int n;
while(cin >> n, n) {
int target = countOnes(n);
for(int i = n+1; ; i++)
if(countOnes(i) == target) { cout << i << '\n'; break; }
}
}
經典「下一個排列」位運算技巧(Next Higher Number with Same Number of 1 Bits):
int nextSameOnes(int n) {
int c = n & -n;
int r = n + c;
return (((r ^ n) >> 2) / c) | r;
}
#include <cstdio>
int main() {
int n;
while(scanf("%d", &n) == 1 && n) {
int c = n & -n;
int r = n + c;
int ans = (((r ^ n) >> 2) / c) | r;
printf("%d\n", ans);
}
return 0;
}
輸入: 1 2 3 4 78 0 輸出: 2 4 5 8 83
位運算技巧將 O(n) 暴力優化為 O(1),是位運算經典應用。理解「最右 01 翻轉 + 右側 1 右移」的邏輯是關鍵。