鱼C论坛

 找回密码
 立即注册
查看: 549|回复: 8

[已解决]如何以单循环赛制随机选出两两对战,每轮比赛胜者再次随机两两对战直至最后决出冠军

[复制链接]
发表于 2020-7-14 16:16:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我的代码是输入比赛人数,是偶数的话,比如8,就先利用evenchoose函数将键盘输入的八位选手随即排序,两两为一组输出,每输出一组随机输入该组的winner并作为元素储存在winner[]数组中,这是第一轮。第二轮是将以第一轮的winner(共四位)为元素的数组winner[]进行evenchoose处理后,再两两为一组输出,每输出一组随机输入该组的winner并作为元素储存在winner[]数组中,这是第二轮。第三轮就是将第二轮的winner做和之前几轮的winner同样的操作,最后决出冠军champin。但是我的代码的执行结果是1.排序的结果并不随机,比如我输入了Bob Lisa Lily Bill Mike John Ann Sara八位选手,第一轮应该是随机的两两分组,Bob Lily和John Sara和Bill Lisa和Ann Mike这样的随机结果,但是我的运行结果是按顺序从第一个Bob直到Sara两两分组输出的,不知道我的程序哪里出错导致了这个结果?  2.在执行到第二轮的时候,当输入第一组的winner后,比如是Bob,点回车直接输出了一个Bob,而不是手动输入第二组的winner,即使想手动输入也输不进去,我想知道这个是什么原因?
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include<time.h>
  4. void evenchoose(char *p[],int b);
  5. int main() {
  6.         int i,j;int number;
  7.         printf("number of gamers:");
  8.         scanf("%d",&number);
  9.         char *name[number][10];
  10.         char winner[16][10];
  11.         for(i=0;i<number;i++)
  12.         {
  13.             scanf("%s",name+i);
  14.         }/*键盘输入最一开始各个选手的名字*/
  15.         if(number%2==0)
  16.         {  evenchoose(name,number);
  17.            for( i=0; i<number; i++) {
  18.                 printf("%-8s",name[i]);
  19.                 if( (i+1)%2==0 ) {
  20.                         printf("\n");
  21.                         printf("the winner of this one match is:");
  22.                         int k=(i+1)/2;
  23.                         scanf("%s",winner[k-1]);

  24.                 }/*第一轮结束*/
  25.         }   number=number/2;
  26.             evenchoose(winner,number);

  27.             while(number!=2)
  28.             {for( i=0; i<number; i++) {
  29.                 printf("%-4s",winner[i]);
  30.                 if( (i+1)%2==0 ) {
  31.                         printf("\n");
  32.                         printf("the winner of this one match is:");
  33.                         int k=(i+1)/2;
  34.                         scanf("%s",winner[k-1]);

  35.                 }number=number/2;
  36.                  evenchoose(winner,number);
  37.         }


  38.             }/*第二轮至倒数第二轮结束*/
  39.             for( i=0; i<number; i++) {
  40.                 printf("%-4s",winner[i]);
  41.                 if( (i+1)%2==0 ) {
  42.                         printf("\n");
  43.                         printf("the champin is:");
  44.                         int k=(i+1)/2;
  45.                         scanf("%s",winner[k-1]);}

  46.         }/*输入champin的名字后最后一轮结束*/}}
  47. /*给数组随机排序的函数*/void evenchoose(char *p[],int b) {
  48.         int j;
  49.         int last=b-1;
  50.         srand((unsigned)time(NULL));
  51.         for(j=0; j<b-1; j++) {
  52.                 int random=rand()%b;
  53.                 char *temp=p[last];
  54.                 p[last]=p[random];
  55.                 p[random]=temp;
  56.                 last--;
  57.         }
  58. }
复制代码

我的理想运行结果示例如下:
number of gamers:8
Bob Lily
the winner of this one match is:Bob
John Sara
the winner of this one match is:Sara
Bill Lisa
the winner of this one match is:Bill
Ann Mike
the winner of this one match is:Mike
Bob Bill
the winner of this one match is:Bob
Sara Mike
the winner of this one match is:Sara
Bob Sara
the champin is:Bob
(冒号后面都是程序运行时要键盘输入的)





最佳答案
2020-7-15 11:03:27
TSwangming 发表于 2020-7-14 23:10
答主可以发一个完整代码吗,时间比较紧急,如果可以的话太谢谢答主了


>= c++ 17

  1. #include <string>
  2. #include <queue>
  3. #include <optional>
  4. #include <iostream>     // std::cout
  5. #include <algorithm>    // std::shuffle
  6. #include <vector>       // std::vector
  7. #include <random>       // std::default_random_engine
  8. #include <chrono>       // std::chrono::system_clock

  9. class Player {
  10. public:
  11.     Player(std::string name) : name(name) {}

  12.     std::string name;
  13. };

  14. class Battle {
  15. public:
  16.     Battle(Player p1, Player p2) : p1(p1), p2(p2) {}

  17.     Player battle() {
  18.         time_t t;
  19.         srand((unsigned int) time(&t));
  20.         if ((rand() & 0x01) != 0) {
  21.             return p1;
  22.         }
  23.         return p2;
  24.     }

  25. private:
  26.     Player p1;
  27.     Player p2;
  28. };

  29. class Round {
  30. public:
  31.     Round(int index) {
  32.         this->next == nullptr;
  33.         this->index = index;
  34.     }

  35.     void enter(Player p) {
  36.         this->players.push(p);
  37.     }


  38.     std::optional<Player> peak() {
  39.         if (this->players.empty()) {
  40.             return std::nullopt;
  41.         }
  42.         auto result = this->players.front();
  43.         this->players.pop();
  44.         return std::optional<Player>(result);
  45.     }

  46.     bool finished() {
  47.         return this->players.size() <= 1;
  48.     }

  49.     Round *start() {
  50.         if (this->next == nullptr) {
  51.             this->next = new Round(this->index + 1);
  52.         }
  53.         while (true) {
  54.             auto player1_result = this->peak();
  55.             if (!player1_result.has_value()) {
  56.                 return this->next;
  57.             }
  58.             Player p1 = player1_result.value();

  59.             auto player2_result = this->peak();
  60.             if (!player2_result.has_value()) {
  61.                 printf("Round: %2d Player: %s 轮空\n", this->index, p1.name.c_str());
  62.                 this->next->enter(p1);
  63.                 return this->next;
  64.             }
  65.             Player p2 = player2_result.value();
  66.             Battle battle(p1, p2);
  67.             Player winner = battle.battle();
  68.             printf("Round: %2d %s vs. %s Winner: %s\n",
  69.                    this->index, p1.name.c_str(), p2.name.c_str(), winner.name.c_str());
  70.             this->next->enter(winner);
  71.         }
  72.     }

  73. private:
  74.     std::queue<Player> players;
  75.     Round *next;
  76.     int index;
  77. };


  78. int main() {
  79.     unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  80.     std::default_random_engine e(seed);

  81.     std::vector<std::string> players = {"Ada", "Barbara", "Calista", "Daisy", "Eartha",
  82.                                         "Faithe", "Gabrielle", "Hannah", "Ida", "Jacqueline"};
  83.     std::shuffle(players.begin(), players.end(), e);

  84.     Round *round = new Round(0);
  85.     for (auto it = players.begin(); it != players.end(); it++) {
  86.         round->enter(Player(*it));
  87.     }

  88.     while (!round->finished()) {
  89.         auto next_round = round->start();
  90.         round = next_round;
  91.     }

  92.     return 0;
  93. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-7-14 16:20:30 | 显示全部楼层
我的程序运行还有乱码现象要怎么解决呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-14 17:52:42 | 显示全部楼层
第一反应是 merkle tree

如果是我做的话,使用面向过程的做法就是,声明两个队列 Q0, Q1

1. 对所有选手进行一次 shuffle,全部进入 Q0
2. 每次从 Q0 中取出两个选手进行 Battle,  胜者进入 Q1, 如果只从 Q0 取出一个人,即轮空,直接进入 Q1
3. 队列从满到空表示一个 Round,当 Round 结束之后,另 Q0 = Q1, Q1 置空,重复2
4. 如果 Q0 只有一个选手,即为冠军

懒得写代码。

如果是面向对象,就去定义 Player, Round, Battle 等类
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-14 18:04:56 | 显示全部楼层
赚小钱 发表于 2020-7-14 17:52
第一反应是 merkle tree

如果是我做的话,使用面向过程的做法就是,声明两个队列 Q0, Q1

我刚刚去搜了一下shuffle发现那个好像不是C语言的东西,我目前只学过C语言。我想问一下我的代码要怎么改呢?源代码搞了好久,不太想变换做法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-14 20:16:50 | 显示全部楼层
本帖最后由 赚小钱 于 2020-7-14 20:20 编辑
TSwangming 发表于 2020-7-14 18:04
我刚刚去搜了一下shuffle发现那个好像不是C语言的东西,我目前只学过C语言。我想问一下我的代码 ...

  1. #include <time.h>
  2. #include <stdlib.h>

  3. void shuffle(int *array, int length) {
  4.     time_t t;
  5.     // 初始化随机因子,让每次执行具有一定的随机性
  6.     srand((unsigned int) time(&t));
  7.     for (int i = 0; i < length; i++) {
  8.         // 找到一个随机的位置 j 与第 i 个位置交换
  9.         int j = (rand() % (length - i)) + i;

  10.         int temp = array[i];
  11.         array[i] = array[j];
  12.         array[j] = temp;
  13.     }
  14. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-14 23:10:25 | 显示全部楼层
赚小钱 发表于 2020-7-14 17:52
第一反应是 merkle tree

如果是我做的话,使用面向过程的做法就是,声明两个队列 Q0, Q1

答主可以发一个完整代码吗,时间比较紧急,如果可以的话太谢谢答主了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-15 11:03:27 | 显示全部楼层    本楼为最佳答案   
TSwangming 发表于 2020-7-14 23:10
答主可以发一个完整代码吗,时间比较紧急,如果可以的话太谢谢答主了


>= c++ 17

  1. #include <string>
  2. #include <queue>
  3. #include <optional>
  4. #include <iostream>     // std::cout
  5. #include <algorithm>    // std::shuffle
  6. #include <vector>       // std::vector
  7. #include <random>       // std::default_random_engine
  8. #include <chrono>       // std::chrono::system_clock

  9. class Player {
  10. public:
  11.     Player(std::string name) : name(name) {}

  12.     std::string name;
  13. };

  14. class Battle {
  15. public:
  16.     Battle(Player p1, Player p2) : p1(p1), p2(p2) {}

  17.     Player battle() {
  18.         time_t t;
  19.         srand((unsigned int) time(&t));
  20.         if ((rand() & 0x01) != 0) {
  21.             return p1;
  22.         }
  23.         return p2;
  24.     }

  25. private:
  26.     Player p1;
  27.     Player p2;
  28. };

  29. class Round {
  30. public:
  31.     Round(int index) {
  32.         this->next == nullptr;
  33.         this->index = index;
  34.     }

  35.     void enter(Player p) {
  36.         this->players.push(p);
  37.     }


  38.     std::optional<Player> peak() {
  39.         if (this->players.empty()) {
  40.             return std::nullopt;
  41.         }
  42.         auto result = this->players.front();
  43.         this->players.pop();
  44.         return std::optional<Player>(result);
  45.     }

  46.     bool finished() {
  47.         return this->players.size() <= 1;
  48.     }

  49.     Round *start() {
  50.         if (this->next == nullptr) {
  51.             this->next = new Round(this->index + 1);
  52.         }
  53.         while (true) {
  54.             auto player1_result = this->peak();
  55.             if (!player1_result.has_value()) {
  56.                 return this->next;
  57.             }
  58.             Player p1 = player1_result.value();

  59.             auto player2_result = this->peak();
  60.             if (!player2_result.has_value()) {
  61.                 printf("Round: %2d Player: %s 轮空\n", this->index, p1.name.c_str());
  62.                 this->next->enter(p1);
  63.                 return this->next;
  64.             }
  65.             Player p2 = player2_result.value();
  66.             Battle battle(p1, p2);
  67.             Player winner = battle.battle();
  68.             printf("Round: %2d %s vs. %s Winner: %s\n",
  69.                    this->index, p1.name.c_str(), p2.name.c_str(), winner.name.c_str());
  70.             this->next->enter(winner);
  71.         }
  72.     }

  73. private:
  74.     std::queue<Player> players;
  75.     Round *next;
  76.     int index;
  77. };


  78. int main() {
  79.     unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  80.     std::default_random_engine e(seed);

  81.     std::vector<std::string> players = {"Ada", "Barbara", "Calista", "Daisy", "Eartha",
  82.                                         "Faithe", "Gabrielle", "Hannah", "Ida", "Jacqueline"};
  83.     std::shuffle(players.begin(), players.end(), e);

  84.     Round *round = new Round(0);
  85.     for (auto it = players.begin(); it != players.end(); it++) {
  86.         round->enter(Player(*it));
  87.     }

  88.     while (!round->finished()) {
  89.         auto next_round = round->start();
  90.         round = next_round;
  91.     }

  92.     return 0;
  93. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-15 11:06:22 | 显示全部楼层
本帖最后由 赚小钱 于 2020-7-15 11:09 编辑


运行结果, 在每一个 Round 开始对所有运动员 shuffle 一下会更好。交给你自己修改吧
  1. Round:  0         Ada vs.      Hannah Winner:      Hannah
  2. Round:  0     Calista vs.      Eartha Winner:      Eartha
  3. Round:  0       Daisy vs.      Faithe Winner:      Faithe
  4. Round:  0  Jacqueline vs.   Gabrielle Winner:   Gabrielle
  5. Round:  0         Ida vs.     Barbara Winner:     Barbara
  6. Round:  1      Hannah vs.      Eartha Winner:      Eartha
  7. Round:  1      Faithe vs.   Gabrielle Winner:   Gabrielle
  8. Round:  1                             Player:     Barbara 轮空
  9. Round:  2      Eartha vs.   Gabrielle Winner:   Gabrielle
  10. Round:  2                             Player:     Barbara 轮空
  11. Round:  3   Gabrielle vs.     Barbara Winner:     Barbara
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-15 11:59:02 | 显示全部楼层
赚小钱 发表于 2020-7-15 11:06
运行结果, 在每一个 Round 开始对所有运动员 shuffle 一下会更好。交给你自己修改吧

太感谢了,剩下的我自己完善
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 10:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表