如何以单循环赛制随机选出两两对战,每轮比赛胜者再次随机两两对战直至最后决出冠军
我的代码是输入比赛人数,是偶数的话,比如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,即使想手动输入也输不进去,我想知道这个是什么原因?#include <stdio.h>#include <stdlib.h>
#include<time.h>
void evenchoose(char *p[],int b);
int main() {
int i,j;int number;
printf("number of gamers:");
scanf("%d",&number);
char *name;
char winner;
for(i=0;i<number;i++)
{
scanf("%s",name+i);
}/*键盘输入最一开始各个选手的名字*/
if(number%2==0)
{evenchoose(name,number);
for( i=0; i<number; i++) {
printf("%-8s",name);
if( (i+1)%2==0 ) {
printf("\n");
printf("the winner of this one match is:");
int k=(i+1)/2;
scanf("%s",winner);
}/*第一轮结束*/
} number=number/2;
evenchoose(winner,number);
while(number!=2)
{for( i=0; i<number; i++) {
printf("%-4s",winner);
if( (i+1)%2==0 ) {
printf("\n");
printf("the winner of this one match is:");
int k=(i+1)/2;
scanf("%s",winner);
}number=number/2;
evenchoose(winner,number);
}
}/*第二轮至倒数第二轮结束*/
for( i=0; i<number; i++) {
printf("%-4s",winner);
if( (i+1)%2==0 ) {
printf("\n");
printf("the champin is:");
int k=(i+1)/2;
scanf("%s",winner);}
}/*输入champin的名字后最后一轮结束*/}}
/*给数组随机排序的函数*/void evenchoose(char *p[],int b) {
int j;
int last=b-1;
srand((unsigned)time(NULL));
for(j=0; j<b-1; j++) {
int random=rand()%b;
char *temp=p;
p=p;
p=temp;
last--;
}
}
我的理想运行结果示例如下:
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
(冒号后面都是程序运行时要键盘输入的)
我的程序运行还有乱码现象要怎么解决呢? 第一反应是 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 等类 赚小钱 发表于 2020-7-14 17:52
第一反应是 merkle tree
如果是我做的话,使用面向过程的做法就是,声明两个队列 Q0, Q1
我刚刚去搜了一下shuffle发现那个好像不是C语言的东西,我目前只学过C语言{:5_100:}。我想问一下我的代码要怎么改呢?源代码搞了好久,不太想变换做法{:9_221:} 本帖最后由 赚小钱 于 2020-7-14 20:20 编辑
TSwangming 发表于 2020-7-14 18:04
我刚刚去搜了一下shuffle发现那个好像不是C语言的东西,我目前只学过C语言。我想问一下我的代码 ...
#include <time.h>
#include <stdlib.h>
void shuffle(int *array, int length) {
time_t t;
// 初始化随机因子,让每次执行具有一定的随机性
srand((unsigned int) time(&t));
for (int i = 0; i < length; i++) {
// 找到一个随机的位置 j 与第 i 个位置交换
int j = (rand() % (length - i)) + i;
int temp = array;
array = array;
array = temp;
}
}
赚小钱 发表于 2020-7-14 17:52
第一反应是 merkle tree
如果是我做的话,使用面向过程的做法就是,声明两个队列 Q0, Q1
答主可以发一个完整代码吗,时间比较紧急,如果可以的话太谢谢答主了{:9_221:} TSwangming 发表于 2020-7-14 23:10
答主可以发一个完整代码吗,时间比较紧急,如果可以的话太谢谢答主了
>= c++ 17
#include <string>
#include <queue>
#include <optional>
#include <iostream> // std::cout
#include <algorithm> // std::shuffle
#include <vector> // std::vector
#include <random> // std::default_random_engine
#include <chrono> // std::chrono::system_clock
class Player {
public:
Player(std::string name) : name(name) {}
std::string name;
};
class Battle {
public:
Battle(Player p1, Player p2) : p1(p1), p2(p2) {}
Player battle() {
time_t t;
srand((unsigned int) time(&t));
if ((rand() & 0x01) != 0) {
return p1;
}
return p2;
}
private:
Player p1;
Player p2;
};
class Round {
public:
Round(int index) {
this->next == nullptr;
this->index = index;
}
void enter(Player p) {
this->players.push(p);
}
std::optional<Player> peak() {
if (this->players.empty()) {
return std::nullopt;
}
auto result = this->players.front();
this->players.pop();
return std::optional<Player>(result);
}
bool finished() {
return this->players.size() <= 1;
}
Round *start() {
if (this->next == nullptr) {
this->next = new Round(this->index + 1);
}
while (true) {
auto player1_result = this->peak();
if (!player1_result.has_value()) {
return this->next;
}
Player p1 = player1_result.value();
auto player2_result = this->peak();
if (!player2_result.has_value()) {
printf("Round: %2d Player: %s 轮空\n", this->index, p1.name.c_str());
this->next->enter(p1);
return this->next;
}
Player p2 = player2_result.value();
Battle battle(p1, p2);
Player winner = battle.battle();
printf("Round: %2d %s vs. %s Winner: %s\n",
this->index, p1.name.c_str(), p2.name.c_str(), winner.name.c_str());
this->next->enter(winner);
}
}
private:
std::queue<Player> players;
Round *next;
int index;
};
int main() {
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine e(seed);
std::vector<std::string> players = {"Ada", "Barbara", "Calista", "Daisy", "Eartha",
"Faithe", "Gabrielle", "Hannah", "Ida", "Jacqueline"};
std::shuffle(players.begin(), players.end(), e);
Round *round = new Round(0);
for (auto it = players.begin(); it != players.end(); it++) {
round->enter(Player(*it));
}
while (!round->finished()) {
auto next_round = round->start();
round = next_round;
}
return 0;
}
本帖最后由 赚小钱 于 2020-7-15 11:09 编辑
赚小钱 发表于 2020-7-15 11:03
>= c++ 17
运行结果, 在每一个 Round 开始对所有运动员 shuffle 一下会更好。交给你自己修改吧
Round:0 Ada vs. Hannah Winner: Hannah
Round:0 Calista vs. Eartha Winner: Eartha
Round:0 Daisy vs. Faithe Winner: Faithe
Round:0Jacqueline vs. Gabrielle Winner: Gabrielle
Round:0 Ida vs. Barbara Winner: Barbara
Round:1 Hannah vs. Eartha Winner: Eartha
Round:1 Faithe vs. Gabrielle Winner: Gabrielle
Round:1 Player: Barbara 轮空
Round:2 Eartha vs. Gabrielle Winner: Gabrielle
Round:2 Player: Barbara 轮空
Round:3 Gabrielle vs. Barbara Winner: Barbara 赚小钱 发表于 2020-7-15 11:06
运行结果, 在每一个 Round 开始对所有运动员 shuffle 一下会更好。交给你自己修改吧
太感谢了,剩下的我自己完善{:5_95:}
页:
[1]