C++经典算法问题:循环赛日程安排问题(分治思想)

C++经典算法问题:循环赛日程安排问题(分治思想)

问题说明

设有n=2k个选手要进行网球循环赛, 要求设计一个满足以下要求的比赛日程表:

(1)每个选手必须与其他n-1个选手各赛一次; (2)每个选手一天只能赛一次。

按此要求,可将比赛日程表设计成一个 n 行n-1列的二维表, 其中,第 i 行第 j 列表示和第 i 个选手在第 j 天比赛的选手。

功能说明

本程序运用分治的思想,实现了循环赛日程安排问题的求解, 生成日程表,输出。

代码简述

通过用户输入数据,程序输入检测,动态分配空间, 调用生成日程表函数,显示输出。

其中,生成日程表函数运用分治的思想,分成separate份, 先安排第一行(第一份),然后每一份填充,最终求解完毕, 生成日程表。

源码示例

#include

#include

using namespace std;

// 循环赛日程安排函数声明

void MatchTable(int k, int n, int **table);

int main()

{

int n = 0, k = 0;

// 用户界面

cout << "---------------- 循环赛日程安排问题 ----------------" << endl;

cout << "请输入k(k>=0),构成 n=(2^k) 个选手的循环赛" << endl;

// 输入k值

cin >> k;

// 判断输入数据合法性,包括检查输入是否为数字,k值是否大于0

if (cin.fail() || k < 0)

{

cout << "输入k错误!" << endl;

system("pause");

return 0;

}

// 计算比赛日程表大小

n = pow(2, k);

// 分配日程表空间

int **table = new int *[n + 1];

for (int i = 0; i <= n; i++)

{

table[i] = new int[n + 1];

}

// 进行循环赛日程安排,生成日程表

MatchTable(k, n, table);

// 显示输出

cout << "------------------------------------------------" << endl;

for (int i = 1; i <= n; i++)

{

for (int j = 1; j <= n; j++)

{

cout << table[i][j] << "\t";

}

cout << endl;

}

cout << "------------------------------------------------" << endl;

// 暂停查看结果

system("pause");

// 释放内存

for (int i = 0; i <= n; i++)

delete[] table[i];

delete[] table;

// 指针置空

table = NULL;

return 0;

}

// 进行循环赛日程安排,生成日程表

void MatchTable(int k, int n, int **table)

{

// 设置日程表第一行的值

for (int i = 1; i <= n; i++)

table[1][i] = i;

// 每次填充的起始填充位置

int begin = 1;

// 用分治法分separate份,循环求解

for (int separate = 1; separate <= k; separate++)

{

// 日程表进行划分

n /= 2;

// flag为每一小份的列的标记

for (int flag = 1; flag <= n; flag++)

{

// 操作行

for (int i = begin + 1; i <= 2 * begin; i++)

{

// 操作列

for (int j = begin + 1; j <= 2 * begin; j++)

{

// 把左上角的值赋给右下角

table[i][j + (flag - 1) * begin * 2] = table[i - begin][j + (flag - 1) * begin * 2 - begin];

// 把右上角的值赋给左下角

table[i][j + (flag - 1) * begin * 2 - begin] = table[i - begin][j + (flag - 1) * begin * 2];

}

}

}

// 进入日程表的下一个划分进行填充

begin *= 2;

}

}

今天的分享就到这里了,大家要好好学C++哟~

写在最后:对于准备学习C/C++编程的小伙伴,如果你想更好的提升你的编程核心能力(内功)不妨从现在开始!

学习C/C++编程知识记得关注“C语言进阶”(就是我咯)

C语言零基础入门教程(83集全):

【C语言】C语言基础教程(C语言程序设计教程 c语言自学教程 c语言零基础入门教程 学习c语言 c语言视频教程 c语音 C语言 C语言学习)_哔哩哔哩_bilibili​www.bilibili.com/video/BV1yb4y197tm?spm_id_from=333.999.0.0

整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)

Copyright © 2022 世界杯金靴|世界杯u20积分榜|1902赵德柱的世界杯珍藏阁|zhaodezhu1902.com All Rights Reserved.