题目

注意,本题使用评测插件进行评测

为了让大家对算法更深的理解,助教们决定以分组对抗的形式举办一场比赛。一共有nn名同学。每个同学都有一个编号——从1到nn的不同的整数。

比赛分多轮,每轮全员参加比赛。同学们被分成两个组,各组可能有不同数量的同学,但每个组必须至少有一名同学。位于不同组的同学之间存在对抗关系。

为了让大家在比赛中被充分调动,助教们希望每对同学都有过对抗关系。但是由于每轮比赛的安排耗费大量精力,助教们希望轮数越少越好。

请你帮助教们安排分组方案。

输入

输入仅一行。

仅一个数为学生人数n(2 ≤ n ≤ 10002 ≤ n ≤ 1000)。

输出

第一行输出mm——最少轮次。

然后有mm行输出。

第i+1i+1行中,先输出 fifi ——第i轮第一组的人数(1 ≤ fi < n1 ≤ fi < n) ,以及fifi个1到nn之间的数字,对应第一组的同学编号。在这轮中,其他同学将在第二组。数字间用空格分隔。同学编号顺序任意。

如果有多个最佳解决方案,请输出其中任何一个。

输入样例1

2

输出样例1

1
1 1

输入样例2

5

输出样例1

3
1 1
3 1 2 3
2 2 4

解题思路

主要是理解二叉树: 这里代码创建了一颗二叉树,节点存储在定义的结构体node中,

  • node里的array存储当前节点数据,

  • length是数组的长度,也就是数据的数量,

  • floor是层数,代表数据位于树的第几层(树有几层,就会有几行输出,树的根节点位于第0层)

  • left和right分别就是左子节点指针和右子节点指针 这里手动实现一颗二叉树帮助大家理解为什么要创建二叉树:(每次分一半,类似于归并排序的方法) 1 2 3 4 5 6 7 | 1 2 3 4 5 6 7 | | 1 2 3 4 5 6 7 | | | 2 3 4 5 6 7 这里一颗关于n = 7,同学编号是1 2 3 4 5 6 7的二叉树的实现过程就实现了,输出时,我们只需要输出每一层中全部的左子树或者全部的右子树即可,比如我们可以这么输出: 3 3 1 2 3 3 1 4 5 3 2 4 6 (第一行的输出是总共的分组数,每行的第一个数字是本行的元素数量)

那么为什么每次分一半最后找出来的组数是最少的呢?

这里用到助教老师的一个提醒:只有每次两组人数基本相等,才能使得每次的分组增加的对抗关系最多,也就是说,每次分组尽量平均分组。

那么为什么这样的二叉树能保证每两个同学都存在一对对抗关系呢?

每次分组都是类似于二分法的分组,也就保证了A组的同学中的每一位已经与B组中的同学对抗过了,因此只需要考虑每组自己的对抗关系即可,所以接下来就A组再分,B组再分,一直循环下去,直到人数变为1,代表着当前路线分组结束。

其他提醒

  • int save[1000][1000] 数组作为存放最终输出的数据存在,数组从下标1开始存储数据,每行元素的0号位存储着当前行的有效数据数量

  • 不要忘记区分.与->在结构体中的使用方法

  • 不要忘记使用malloc函数为新创建的结构体指针赋值存储空间,我因为这个错误检查了好久

  • 代码的解释具体见代码注释

C代码

#include <stdio.h>
#include<stdlib.h>int save[1000][1000] = {0};struct node {int array[1000];int length;int floor;struct node *left;struct node *right;
};int frequence(int n) {int fre = 0;while (n != 1) {if (n % 2 != 0) {n = (n / 2) + 1;} else if (n % 2 == 0) {n = n / 2;}fre++;}return fre;
}// addNode方法:以根节点为中心,添加所有子节点
void addNode(struct node *fatherNode) {struct node *cn_left, *cn_right; //两个子节点,cn的意思是childnode子节点cn_left = (struct node *) malloc(sizeof(struct node));cn_right = (struct node *) malloc(sizeof(struct node));int n = fatherNode->length;if (fatherNode->length == 1) {return;} else if (n % 2 != 0) {// 奇数个元素时,左子节点分配n / 2个元素,右子节点分配(n / 2) + 1个元素// 左子节点赋值cn_left->length = n / 2;cn_left->floor = fatherNode->floor + 1;for (int i = 0; i < cn_left->length; ++i) {cn_left->array[i] = fatherNode->array[i];}cn_left->left = NULL;cn_left->right = NULL;// 右子节点赋值cn_right->length = (n / 2) + 1;cn_right->floor = fatherNode->floor + 1;for (int i = 0; i < cn_right->length; ++i) {cn_right->array[i] = fatherNode->array[i + (n / 2)];}cn_right->left = NULL;cn_right->right = NULL;// 确认父子节点关系fatherNode->left = cn_left;fatherNode->right = cn_right;// 递归赋值addNode(cn_left);addNode(cn_right);} else if (n % 2 == 0) {// 元素个数为偶数个,左子节点和右子节点平均分配元素数量// 左子节点赋值cn_left->length = n / 2;cn_left->floor = fatherNode->floor + 1;for (int i = 0; i < cn_left->length; ++i) {cn_left->array[i] = fatherNode->array[i];}cn_left->left = NULL;cn_right->right = NULL;// 右子节点赋值cn_right->length = n / 2;cn_right->floor = fatherNode->floor + 1;for (int i = 0; i < cn_right->length; ++i) {cn_right->array[i] = fatherNode->array[i + (n / 2)];}cn_right->left = NULL;cn_right->right = NULL;// 确认父子节点关系fatherNode->left = cn_left;fatherNode->right = cn_right;// 递归赋值addNode(cn_left);addNode(cn_right);}
}// search方法用于检索所有的节点,并将信息存储在save数组中
void search(struct node *fatherNode) {// array数组下标从1开始,每行数组的第一个元素存放当前行有多少个元素,从下标1开始才是元素内容if ((fatherNode->left == NULL || fatherNode->right == NULL)) {
//        printf("just end!\n");return;}struct node *cn_left,*cn_right;
//    cn_left = (struct node *) malloc(sizeof(struct node));cn_left = fatherNode->left;cn_right = fatherNode->right;int index = cn_left->floor;
//    printf("index = %d\n", index);int length = cn_left->length;int length_start = save[index][0];save[index][0] += length;for (int i = 1 + length_start, j = 0; i <= length + length_start; ++i, ++j) {save[index][i] = cn_left->array[j];}search(cn_left);search(cn_right);}int main() {
//    printf("please input a number for n :");int n = 0, fre;scanf("%d", &n);int array_main[n];for (int i = 0; i < n; ++i) {array_main[i] = i + 1;}struct node mainNode;for (int i = 0; i < n; ++i) {mainNode.array[i] = i + 1;}mainNode.length = n;mainNode.floor = 0;fre = frequence(n);printf("%d\n", fre);addNode(&mainNode);search(&mainNode);// 遍历输出save数组for (int i = 1; i <= fre; ++i) {printf("%d ", save[i][0]);for (int j = 1; j <= save[i][0]; ++j) {printf("%d ", save[i][j]);}printf("\n");}}

北航2020级算法上机 C1-I 对抗 题解相关推荐

  1. 北航2018级算法期末上机部分题解

    北航2018级算法期末第二次上机考试部分题解 C题 三角形 题目描述 数据大小 输入 输出 解题思路 题解代码 D 魔术 题目描述 数据描述 输入 输出 解题思路 题解代码 E 乘法 题目描述 输入 ...

  2. 北航2017级算法第一次上机---芸如的入学测试

    题目链接 芸如的入学测试 解题思路 假期闲来无事,复习下算法,这些题2018级的学弟学妹们搞不好上机的时候也会被坑到. 这个题的思想是前缀和思想,这个思想大家可以自行百度,这里主要说一下取模的问题. ...

  3. 北航2017级算法第一次上机---SkyLee的艾露猫

    题目链接 SkyLee的艾露猫 解题思路 斐波那契数列的变形 通过递推得知,在3-12年的时候艾露猫正在成年期,每年都会生小猫,一对成年猫生一对小猫,即cat[i]=cat[i−1]+cat[i−2] ...

  4. A1-2017级算法上机第一次练习赛 H 模式寻对

    概念回顾 逆序对:数列a[0],a[1],a[2]-中的任意两个数a[i],a[j], 如果i<j, 并且a[i]>a[j], 那么我们就说这两个数构成了一个逆序对. 逆序数:一个数列中逆 ...

  5. A1-2017级算法上机第一次练习赛 J 怠惰的园丁王木木

    题目描述 Magry同学家里请了一个怠惰的园丁王木木,主要工作就是除草,现在有高度为1,2,3...n的草,王木木很懒,想找到一种最简单的方式把所有草全除光. 王木木每点体力可以将一根或者多根草减掉相 ...

  6. A1-2017级算法上机第一次练习赛 K 画个圈圈诅咒你

    题目描述 AlvinZH最近很慌,先是被宋老师一句 "和我们有关系吗" 吓的不行,然后又被原老师批判了一番 "害怕" ,小日子整天过的提心吊胆的,没准儿这题就是 ...

  7. 2017级算法模拟上机准备篇(一)

    回顾一下往年的考题知识点: The Last Battle!! 2014级算法期末上机 简单题--I wanna be the 升级者Ⅰ 结构体排序  STL:sort() 简单题--I wanna ...

  8. 【调剂】广州大学“方滨兴院士班”(硕士班)欢迎2020级全国网络安全爱好者调剂...

    点击文末的阅读原文或者公众号界面左下角的调剂信息或者公众号回复"调剂"是计算机/软件等专业的所有调剂信息集合,会一直更新的. 广州大学"方滨兴院士班"(硕士班) ...

  9. 北航计算机2014复试上机题,北航计算机系考研复试上机真题及答

    北航计算机系考研复试上机真题及答 (29页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 Kao400.com 出品 侵权必究 北京航空航 ...

最新文章

  1. 百万粉女极客突袭深圳手机公司:你们说想要源码就来自取?我来了
  2. 最详细的NLP开源数据集分享--包含342个公开数据集
  3. ARP协议全面实战手册——协议详解、攻击与防御(内部资料)
  4. 升级oracle spu,Oracle 2017改变:新补丁更新(RU和RUR),新的版本(Release 18和19)
  5. 常见的物联网通信协议
  6. 将String类型的Json字符串转化对象或对象数组
  7. 建设研发运营一体化平台
  8. 【对讲机的那点事】450MHz模拟无线列调的工作原理(连载五)
  9. 边缘计算精华问答 | 5G是否会“逼退”4G?
  10. acer清理工具 clear下载_免流量工具聚合下载,包含全部工具
  11. Hbase常用数据库操作类
  12. Java 基础 —— enum
  13. Atitit.印章文化 印章的起源历史与发展 v2 r99 .docx
  14. 计算机专业考研电路原理,2016年南开大学综合基础课(模拟电路、数字电路、计算机原理)考研试题.pdf...
  15. 成语接龙 你看过这么拽的吗?
  16. #17-【二分】gdgzoi::比赛.Contest2281.Problem D (包裹快递)(zly#1)
  17. 微信小程序中使用Echarts 折线图、柱形图、饼状图
  18. 百度搜索框代码,实现回车点击,跳转到新页面,简单
  19. 二清资金监管户账务处理实例
  20. 北京妙计旅行 后台开发实习一面二面

热门文章

  1. 中兴视讯服务器 广州,中兴通讯推出全新高清视讯解决方案
  2. 9.ESP32--ADC
  3. Wandb——Pytorch模型指标可视化及超参搜索
  4. php webmail,10个基于Ajax的PHP Webmail客户端
  5. CDOJ 1347柱爷的矩阵(二维dp)
  6. Python是什么编程语言
  7. 计算机毕业设计Java校园闲置物品交易平台(系统+源码+mysql数据库+lw文档)
  8. 如何拆分含有多种分隔符的字符串
  9. 微软苏州校招1月3日在线编程题1——constellations
  10. 微生物组学测序十大错误认知