Codeforces 1424J:极限操作,祭出祖传 C++
2024-02-22 18:24:52
Codeforces 1424J:用尽洪荒之力
今天我们来看一道 Codeforces 的 1424J 题。这是一道中等难度的题目,需要我们运用数论和循环的知识来解决。
题目
给你一个正整数 n,求满足以下条件的正整数 k 的个数:
- k 是 n 的倍数。
- k 的二进制表示中,1 的个数是偶数。
输入格式
一行一个整数 n。
输出格式
一行一个整数,表示满足条件的 k 的个数。
样例输入
10
样例输出
4
算法分析
这道题的难点在于如何判断一个数的二进制表示中 1 的个数是偶数。我们可以使用位运算来解决这个问题。
首先,我们可以使用 n & (n - 1) 来得到 n 的二进制表示中最后一个 1 的位置。然后,我们可以使用 n & ((n - 1) >> 1) 来得到 n 的二进制表示中倒数第二个 1 的位置。依次类推,我们可以得到 n 的二进制表示中所有 1 的位置。
如果 n 的二进制表示中 1 的个数是偶数,那么最后一个 1 的位置一定也是偶数。因此,我们可以使用以下代码来判断一个数的二进制表示中 1 的个数是偶数:
bool is_even_ones(int n) {
int last_one = n & (n - 1);
return (last_one & 1) == 0;
}
有了这个函数,我们就可以很容易地解决这道题了。我们可以遍历所有 n 的倍数,并使用 is_even_ones 函数判断每个倍数的二进制表示中 1 的个数是否偶数。如果偶数,则计数器加 1。
代码实现
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int count = 0;
for (int i = 1; i <= n; i++) {
if (i % n == 0 && is_even_ones(i)) {
count++;
}
}
cout << count << endl;
return 0;
}
复杂度分析
这道题的时间复杂度为 O(n),其中 n 是给定的正整数。这是因为我们遍历了所有 n 的倍数,并对每个倍数进行了 O(1) 操作。
优化技巧
这道题可以进一步优化。我们可以注意到,如果 n 是奇数,那么满足条件的 k 一定是偶数。因此,我们可以只遍历 n 的偶数倍数,这样可以将时间复杂度优化到 O(n / 2)。
总结
这道题是一道很好的数论题,它考察了我们对位运算和循环的理解。通过使用 is_even_ones 函数,我们可以很容易地判断一个数的二进制表示中 1 的个数是偶数。这道题也可以进一步优化,以减少时间复杂度。