zl程序教程

您现在的位置是:首页 >  其他

当前栏目

三维数组解决问题案例(天梯赛座位分配)

案例数组 分配 三维 解决问题 天梯
2023-09-14 09:14:24 时间

三维数组解决问题案例

简介:通过天梯赛座位分配,这个算法题,我们来理解通过2维以上的数组解决算法问题。

/* 天梯赛座位分配 (20 分)

天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情。为此我们制定如下策略:假设某赛场有 N 所学校参赛,第 i 所学校有 M[i] 支队伍,
每队 10 位参赛选手。令每校选手排成一列纵队,第 i+1 队的选手排在第 i 队选手之后。从第 1 所学校开始,各校的第 1 位队员顺次入座,然后是各校的第 2 位队员…… 以此类推。如果最后
只剩下 1 所学校的队伍还没有分配座位,则需要安排他们的队员隔位就坐。本题就要求你编写程序,自动为各校生成队员的座位号,从 1 开始编号。
输入格式:

输入在一行中给出参赛的高校数 N (不超过100的正整数);第二行给出 N 个不超过10的正整数,其中第 i 个数对应第 i 所高校的参赛队伍数,数字间以空格分隔。
输出格式:

从第 1 所高校的第 1 支队伍开始,顺次输出队员的座位号。每队占一行,座位号间以 1 个空格分隔,行首尾不得有多余空格。另外,每所高校的第一行按“#X”输出该校的编号X,从 1 开始。
输入样例:

3
3 4 2

输出样例:

#1
1 4 7 10 13 16 19 22 25 28 // 稍微观察下就可以看出这个编号的规律,从上往下看
31 34 37 40 43 46 49 52 55 58
61 63 65 67 69 71 73 75 77 79
#2
2 5 8 11 14 17 20 23 26 29
32 35 38 41 44 47 50 53 56 59
62 64 66 68 70 72 74 76 78 80
82 84 86 88 90 92 94 96 98 100
#3
3 6 9 12 15 18 21 24 27 30
33 36 39 42 45 48 51 54 57 60
*/

// 解决方案一(三维数组的应用)

// 对于三维数组的空间结构或者是储存结构的理解:一维数组 int a[i],它是一条线(专业的说是一片连续的储存空间进行存储) ,二维数组 int a[i][j] , 它是由多条线
// 共同组成的一个面(上面题目里面的每个矩阵都是二维数组,每一行都是一个一维数组) ,三维数组就是多个平行的平面(二维数组)组成,当然目前直观的来看只能显示
// 出一维数组和二维数组直观的样子,以此类推四维数组是可以想象成由很多个球构成,每个球里面装着多个三维数组,明白这些以后即使是10位数组都很好理解。

#include<stdio.h>

int main(void)
{
	int n, i, j, k, num = 0, max = 0, lasti = -1;  // n 是高校数目,i, j, k分别是学校的编号,队伍的编号,队伍中每个人的编号, max是存放队伍数量的最大值,lasti是记录是否有两次编号都是同一个学校 
	int a[100][10][10];                            // 这里定义的是一个三维数组 
	int m[100];									   // 这个数字是存放每个学校的队伍数目 
	scanf ("%d", &n);
	for (i = 0; i < n; i++)						   // 对每个学校的队伍数目进行输入 
	{
		scanf ("%d", m + i); 
		if (max < m[i])							   // 寻找队伍数量的最大值
		{
			max = m[i];
		}
	}
	for (j = 0; j < max; j++)    					// 这里的第一个循环变量是队伍编号, 根据题目条件是先把每个学校的最前面的队伍编完后再编写后面的队伍 
	{
		for (k = 0; k < 10; k++)					// 这第二个循环是以每个队伍学生数目为变量, 题目要求每个队伍最多10个人 
		{
			for (i = 0; i < n; i++)					// 第三个循环是以学校的编号为变量,根据题目的例子,第一号在第一个学校,第二号在第二个学校,第三号在第三个学校。。。 
			{									
													
				if (j < m[i])					    // 这个条件的目的j表示的是当前的队伍编号,m[i] 是这个学校队伍的数量,j从0开始 
				{									// 先看判断条件之外的语句更好理解这里
				
					if (lasti == i)     			// 这个条件的意思是当两次都是同一个学校的时候表示的就是上面题目中 “只剩下 1 所学校的队伍还没有分配座位,则需要安排他们的队员隔位就坐” 
					{
						num += 2;					// 然后num每次这次就要+2,跳了一个人 
					}
					else
					{
						num++;						// 反之没有的话就+1 
					}
					a[i][j][k] = num; 				// num表示的是当前学生的序号,a[i][j][k], 表示的是当前学生的位置,最开始初始化为0,还没有编号 
					lasti = i;						// lasti表示的就是上一个学生所在的学校编号, 最开始有初始化为-1,不代表任意学校 
				}
			}
		}
	}
	for (i = 0; i < n; i++)							// 输出的时候注意下就好了 
	{
		printf ("#%d\n", i + 1); 					// i代表的就是学校编号 
		for (j = 0; j < m[i]; j++)					// 每一队伍 
		{
			for (k = 0; k < 9; k++)					//每个人 
			{
				printf ("%d ", a[i][j][k]);
			}
			printf ("%d\n", a[i][j][k]);
		}
	}
	return 0;
}