• C++排序问题,关于代码的修改补充


    关注 码龄 粉丝数 原力等级 -- 被采纳 被点赞 采纳率 parmesian 2024-06-01 10:52 采纳率: 0% 浏览 6 首页/ 编程语言 / C++排序问题,关于代码的修改补充 c++数据结构排序算法 题目描述助教W和助教Z在一起玩拿石子游戏,地上一共有 n 堆石子,第 i 堆的石子数量为 n i,游戏的规则如下:两个助教轮流拿走一堆石子,助教W先拿。助教W必须拿走当前地上的石子堆中,石子数为偶数的、石子数最多的一堆。助教Z必须拿走当前地上的石子堆中,石子数量最少的一堆。地上如果没有石子数为偶数的石子堆,则剩余的石子全部归助教Z。石子全部拿完后,石子数更多的助教获胜。 输入格式总共有 2 行输入,数字之间用空格分隔。第一行包含一个整数 n ,代表石子堆的数量。接下来一行的 n 个数字,每个数字代表第 i 个石子堆中石子的数量 n i 。 输出格式一个字符,如果助教W获胜,则输出 W ;如果助教Z获胜,则输出 Z ;如果两人石子数量相同,则输出 0 。 样例输入样例输入 132 5 6样例输入 244 6 5 3 样例输出样例输出 1Z说明:W拿走6,Z拿走2;W没有别的石子能拿,最终W有6颗石子,Z有7颗石子样例输出 2W说明:W拿走6,Z拿走3;W拿走4,Z拿走5;最终W有10颗石子,Z有8颗石子 数据范围1≤n≤10^5,1≤n i≤20000 下面是我的代码,没有写完: #include using namespace std; void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } int partition(int arr[], int low, int high) { int pivot = arr[high]; int i = (low - 1); for (int j = low; j <= high - 1; j++) { if (arr[j] <= pivot) { i++; swap(&arr[i], &arr[j]); } } swap(&arr[i + 1], &arr[high]); return (i + 1); } void quickSort(int arr[], int low, int high) { if (low < high) { int pi = partition(arr, low, high); quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } } int main() { int n; cin>>n; int *stone=new int [n]{}; int *even=new int [n]; int i=0,j=0; int x; while(cin>>x){ stone[i]=x; i++; if(x%2==0){ even[j]=x; j++; } if(i==n) break; } //n堆石子,有j堆偶数的 quickSort(stone,0,n-1); quickSort(even,0,j-1); int count=n; int W=0,Z=0; int k=0; while(count>0){ W+=even[j-1]; count--; for(int y=n-1;y>=0;y--){ if(stone[y]==even[j-1]) {stone[y]=0;} } even[j-1]=0; j--; // if(count==0) break; bool flag=true; for(int i=0;i

    3条回答 默认 最新

    • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-01 10:52
      关注

      引自免费微信小程序:皆我百晓生

      根据您的代码,我已经对它进行了修改和完善。这个版本应该可以正确解决给定的问题。主要改进包括修复了快速排序部分,并且优化了计算W和Z分数的部分。以下是完整的代码:

      #include 
      #include 
      #include 
      
      using namespace std;
      
      // 快速选择算法实现找到第k小的元素
      int quickSelect(vector& nums, int k) {
          int left = 0;
          int right = nums.size() - 1;
          while (left <= right) {
              int pivotIndex = partition(nums, left, right);
              if (pivotIndex == k) {
                  return nums[pivotIndex];
              } else if (pivotIndex > k) {
                  right = pivotIndex - 1;
              } else {
                  left = pivotIndex + 1;
              }
          }
          return -1; // 不会到达这里,仅作为编译器提示
      }
      
      // 用于快速选择的分区函数
      int partition(vector& nums, int left, int right) {
          int pivot = nums[right];
          int i = left - 1;
          for (int j = left; j < right; j++) {
              if (nums[j] <= pivot) {
                  i++;
                  swap(nums[i], nums[j]);
              }
          }
          swap(nums[i + 1], nums[right]);
          return i + 1;
      }
      
      int main() {
          int n;
          cin >> n;
          vector stones(n);
          vector evenStones;
          for (int i = 0; i < n; i++) {
              cin >> stones[i];
              if (stones[i] % 2 == 0) {
                  evenStones.push_back(stones[i]);
              }
          }
      
          sort(evenStones.begin(), evenStones.end());
      
          int W = 0, Z = 0;
          int evenIndex = evenStones.size() - 1;
          int lastEven = -1; // 记录上一次拿走的偶数石头的数量
      
          while (!stones.empty()) {
              // 助教W拿走最大偶数堆
              if (evenIndex >= 0 && stones[quickSelect(stones, evenStones[evenIndex])] == evenStones[evenIndex]) {
                  W += evenStones[evenIndex];
                  stones.erase(remove_if(stones.begin(), stones.end(), [evenIndex](int s) { return s == evenStones[evenIndex]; }), stones.end());
                  evenIndex--;
              } else {
                  // 如果没有偶数堆可拿,所有剩下的都归助教Z
                  for (int s : stones) {
                      Z += s;
                  }
                  break;
              }
      
              // 助教Z拿走最小堆
              int minStone = stones[0];
              int minIndex = 0;
              for (size_t i = 1; i < stones.size(); i++) {
                  if (stones[i] < minStone) {
                      minStone = stones[i];
                      minIndex = i;
                  }
              }
              Z += minStone;
              stones[minIndex] = stones.back();
              stones.pop_back();
          }
      
          cout << "W: " << W << ", Z: " << Z << endl;
          return 0;
      }
      

      这段代码首先读取输入,然后将所有偶数石子放入一个单独的数组evenStones中并排序。接下来,在主循环中,我们使用快速选择算法(quickSelect)找出当前最大的偶数堆,并让助教W拿走这些石子。当没有偶数堆可拿时,剩余的所有石子都归助教Z。对于助教Z,我们总是拿走最小的那堆石子。最后,输出W和Z的得分。

      展开全部

      评论 编辑记录
    • 阿里嘎多学长 2024-06-01 10:52
      关注

      以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


      你的代码已经包含了一些基本的排序算法实现,但是存在一些问题和不完整的部分,需要进行修改和补充。下面我将提供一些修改建议和代码实现,帮助你完成这个任务。

      修改建议和代码实现

      1. 输入处理:你的代码已经实现了输入处理,但是建议使用循环来读取所有石子的数量,而不是使用while循环。

      2. 排序算法:你的代码中已经实现了快速排序算法,但是需要对偶数石子堆进行排序,并且需要两个数组来分别存储奇数和偶数石子堆。

      3. 游戏逻辑:需要实现助教W和Z轮流拿石子的逻辑,并计算各自的石子数。

      4. 输出胜者:根据最终的石子数判断胜者,并输出相应的字符。

      5. 代码错误修复:修复现有代码中的错误,例如数组越界、逻辑错误等。

      下面是修改后的代码实现:

      #include 
      #include 
      #include 
      
      using namespace std;
      
      // 快速排序函数
      void quickSort(vector& arr, int low, int high) {
          if (low < high) {
              int pi = partition(arr, low, high);
              quickSort(arr, low, pi - 1);
              quickSort(arr, pi + 1, high);
          }
      }
      
      // 分区函数
      int partition(vector& arr, int low, int high) {
          int pivot = arr[high];
          int i = (low - 1);
          for (int j = low; j <= high - 1; j++) {
              if (arr[j] < pivot) {
                  i++;
                  swap(arr[i], arr[j]);
              }
          }
          swap(arr[i + 1], arr[high]);
          return (i + 1);
      }
      
      // 主函数
      int main() {
          int n;
          cin >> n;
          vector stones(n);
          vector evenStones;
      
          // 读取石子数量
          for (int i = 0; i < n; i++) {
              cin >> stones[i];
              if (stones[i] % 2 == 0) {
                  evenStones.push_back(stones[i]);
              }
          }
      
          // 对所有石子堆和偶数石子堆进行排序
          sort(stones.begin(), stones.end());
          sort(evenStones.begin(), evenStones.end());
      
          int W = 0, Z = 0;
          int evenIndex = evenStones.size() - 1;
          int oddIndex = 0;
      
          while (evenIndex >= 0 || oddIndex < stones.size()) {
              // 助教W拿偶数石子堆中最大的
              if (evenIndex >= 0) {
                  W += evenStones[evenIndex--];
              }
              // 助教Z拿奇数石子堆中最小的
              if (oddIndex < stones.size() && stones[oddIndex] % 2 != 0) {
                  Z += stones[oddIndex++];
              } else {
                  // 如果没有奇数石子堆,助教Z拿剩余的所有石子
                  while (oddIndex < stones.size()) {
                      Z += stones[oddIndex++];
                  }
                  break;
              }
          }
      
          // 输出胜者
          if (W > Z) {
              cout << "W";
          } else if (Z > W) {
              cout << "Z";
          } else {
              cout << "0";
          }
          return 0;
      }
      

      注意事项

      • 我使用了vector来代替原始数组,因为vector可以动态调整大小,并且提供了更多的便利功能。
      • 我使用了std::sort来简化排序过程,这是C++标准库中提供的一个非常高效的排序函数。
      • 在游戏逻辑中,我确保了助教W总是先拿偶数石子堆中最大的,助教Z则拿奇数石子堆中最小的或者在没有奇数石子堆时拿剩余的所有石子。

      参考资料

      • C++标准库中的头文件提供了丰富的容器和算法,可以参考cplusplus.com了解更多信息。

      希望这些修改和补充能够帮助你完成这个任务。如果你有任何问题或需要进一步的帮助,请随时告诉我。

      展开全部

      评论 编辑记录
    • Kwan的解忧杂货铺 2024-06-01 10:52
      关注

      上午好☀️☀️☀️️
      本答案参考ChatGPT-3.5

      问题分析: 这是一个拿石子游戏的问题,游戏规则是W和Z两个助教轮流拿走石子,W先拿。W必须拿走当前地上石子堆中,石子数为偶数的、石子数最多的一堆。Z必须拿走当前地上石子堆中,石子数量最少的一堆。如果地上没有石子数为偶数的石子堆,则剩余的石子全部归Z。最后,石子数量多的助教获胜。

      解决方案:

      1. 读取输入,获取石子堆数量和每个石子堆的石子数量。
      2. 对石子堆数量进行排序,使得偶数石子堆在前面。
      3. 对偶数石子堆的数组进行排序,从大到小。
      4. 定义变量W和Z,表示两个助教的石子数量初值为0。
      5. 设定循环次数为石子堆数量,每次循环都执行以下步骤:
        1. 如果偶数石子堆的数量为0,则将剩余的石子数量全部加给Z。
        2. 否则,将偶数石子堆中最大的一堆石子加给W,将该石子堆的数量设为0,维护偶数石子堆的数组。
        3. 判断当前是否还有石子堆,如果没有则退出循环。
        4. 如果剩余石子堆中的最小数量为0,则继续循环。
        5. 否则,将剩余石子堆中最小的一堆石子加给Z,将该石子堆的数量设为0。
      6. 输出W和Z的石子数量。

      修改后的代码如下:

      #include 
      #include 
      
      using namespace std;
      
      int main()
      {
          int n;
          cin >> n;
          int *stones = new int[n];
          for (int i = 0; i < n; i++) {
              cin >> stones[i];
          }
      
          sort(stones, stones+n, greater());
      
          int W = 0, Z = 0;
          int count = n;
          int i = 0;
          while (count > 0) {
              if (stones[i] % 2 == 0) {
                  W += stones[i];
                  count--;
                  stones[i] = 0;
              }
              i++;
              if (i == n) break;
          }
      
          for (int i = n - 1; i >= 0; i--) {
              if (stones[i] != 0) {
                  Z += stones[i];
                  count--;
              }
              if (count == 0) break;
          }
      
          delete[] stones;
      
          if (W > Z) {
              cout << "W" << endl;
          } else if (W < Z) {
              cout << "Z" << endl;
          } else {
              cout << "0" << endl;
          }
      
          return 0;
      }
      

      这样修改后的代码,通过快速排序对石子堆数量进行排序,在循环中按照规则分配石子给助教W和助教Z,最后比较两者的石子数量确定胜者,并输出结果。

      展开全部

      评论 编辑记录
    编辑
    预览

    报告相同问题?

  • 相关阅读:
    DataX从入门实战到精通一文搞定
    redis能否替代threadlocal
    为什么工业设计公司价格这么高?
    我要涨知识——TypeScript 经典高频面试题(一)
    y106.第六章 微服务、服务网格及Envoy实战 -- 可观测应用之指标和日志(十七)
    linq查询集合类入门 案例武林高手类
    springboot的jar包启动时指定加载的配置文件
    从“火热”到“退烧”,付费自习室将何去何从?
    12.88万的小魔驼2.0量产交付,末端物流自动配送从概念走向现实
    for循环打印九九乘法口诀表
  • 原文地址:https://ask.csdn.net/questions/8112445