返回

Codeforces 1424J:极限操作,祭出祖传 C++

人工智能

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 的个数是偶数。这道题也可以进一步优化,以减少时间复杂度。