当前位置:   article > 正文

蓝桥杯 2022 省A 选数异或

蓝桥杯 2022 省A 选数异或

一种比较无脑暴力点的方法,时间复杂度是(n²+m)。
(注意==的优先级比^高,记得加括号(a[i]^a[j])==x)

  1. #include <iostream>
  2. #include <vector>
  3. #include <bits/stdc++.h> // 包含一些 C++ 标准库中未包含的特定实现的函数的头文件
  4. using namespace std;
  5. int main() {
  6. int n, m, x;
  7. // 输入 n(数组长度)、m(查询次数)、x(给定的异或值)
  8. cin >> n >> m >> x;
  9. // 定义数组 a 存储 n 个整数
  10. int a[n + 1];
  11. // 输入 n 个整数到数组 a 中
  12. for (int i = 1; i <= n; i++) {
  13. cin >> a[i];
  14. }
  15. // 定义动态规划数组 dp,初始化为 INT_MAX,记录a[i]第一次能异或为x的位置j。
  16. vector<int> dp(n + 1, INT_MAX);
  17. // 对于每对 i、j,判断 a[i] 和 a[j] 是否异或等于给定的 x
  18. // 如果等于,则更新 dp[i] 为 j,表示 a[i] 和 a[j] 可以异或得到 x
  19. for (int i = 1; i < n; i++) {
  20. for (int j = i + 1; j <= n; j++) {
  21. if ((a[i] ^ a[j]) == x) {
  22. dp[i] = j;
  23. break; // 找到第一个符合条件的 j 即可跳出内层循环
  24. }
  25. }
  26. }
  27. // 对于每次查询,输入左右边界 l、r
  28. // 如果 l 不等于 r 并且 dp[l] 小于等于 r,则输出 "yes",否则输出 "no"
  29. for (int i = 0; i < m; i++) {
  30. int l, r;
  31. cin >> l >> r;
  32. if (l != r && dp[l] <= r)
  33. cout << "yes" << endl;
  34. else
  35. cout << "no" << endl;
  36. }
  37. return 0;
  38. }

但是显然这样是不能得满分的,那么我们就要优化一下思路。

思路分析:

  1. 定义数组 a 存储 n 个整数。
  2. 定义一个 map<int, int>,用于记录数组元素和它们的位置信息。(注意:map当某个键不存在时,其值会被初始为0)
  3. 从标准输入流中读取 n 个整数到数组 a 中。
  4. 定义动态规划数组 dp,初始化为 0,用于记录满足条件的[1,i]最远位置。
  5. 遍历数组 a,更新动态规划数组 dpmap
  6. 查询部分:从标准输入流中读取左右边界 lr,判断是否存在满足条件的位置对,输出相应的结果。
  1. #include<iostream>
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. int main() {
  5. int n, m, x;
  6. // 输入数组长度 n、查询次数 m 和给定的异或值 x
  7. cin >> n >> m >> x;
  8. // 定义数组 a 存储 n 个整数
  9. int a[n + 1];
  10. // 定义 map,用于记录数组元素和它们的位置信息
  11. map<int, int> map;
  12. // 输入 n 个整数到数组 a 中
  13. for(int i = 1; i <= n; i++) {
  14. cin >> a[i];
  15. }
  16. // 定义动态规划数组 dp,初始化为 0,用于记录满足条件的最远位置
  17. vector<int> dp(n + 1, 0);
  18. // 对数组 a 进行遍历
  19. for(int i = 1; i <= n; i++) {
  20. // 更新动态规划数组 dp
  21. // dp[i] 表示在位置 i 时,可以得到的满足条件的最远位置
  22. // 比较当前位置和之前出现的值对应位置的较大值,更新 dp[i]
  23. dp[i] = max(dp[i - 1], map[a[i] ^ x]);
  24. // 更新 map,记录当前元素的位置信息
  25. map[a[i]] = i;
  26. }
  27. // 查询部分
  28. for(int i = 0; i < m; i++) {
  29. int l, r;
  30. cin >> l >> r;
  31. // 如果左右边界不相等,并且 dp[r] 大于等于左边界 l,则输出 "yes",否则输出 "no"
  32. if(l != r && dp[r] >= l)
  33. cout << "yes" << endl;
  34. else
  35. cout << "no" << endl;
  36. }
  37. return 0;
  38. }

时间复杂度是O(n+m),大大优化了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/334390
推荐阅读
相关标签
  

闽ICP备14008679号