L1-049 天梯赛座位分配 (20分)

本文介绍了一种解决天梯赛座位分配问题的算法,通过巧妙的循环和标记使用,实现了队员的合理分配,尤其关注了“隔位就坐”的特殊条件。代码采用C++实现,展示了非传统循环应用和模拟法的高效性。

L1-049 天梯赛座位分配 (20分)

这题改变了我对循环使用的腐朽看法,增加了标记的使用,模拟法
关键点是题干:“如果最后只剩下 1 所学校的队伍还没有分配座位,则需要安排他们的队员隔位就坐。”
#include<bits/stdc++.h>
int main(void)
{
    int n,num[111],maxi=0,max=0;
    
    scanf("%d",&n);					//input;
    for(int i=0;i<n;i++){
    	scanf("%d",&num[i]);
    	if(num[i]>max) max = num[i];	//process;
	}
	int a[111][11][11]; 	//a[school-i][team-j][people-k];
	int i,j,k;
	int prei=-1,step=0;
	
	//循环并非常规的从外到内,而是根据需要选择内外循环,很有技巧性,很机智(也打破了我一般的常规思想,是进步的点)! 
	for(j=0;j<max;j++){		//最外层提前找到最大数量的team然后遍历
							//(其实这里编代码的时候是要构思好再实现的
							//但是如果是直接一次性下来,这个max可以改成函数返回一个最大值,比较清楚, 
		for(k=0;k<10;k++){	//然后学校循环结束,就是横向的每个队员进入座位;1--10循环(0--9) 
			for(i=0;i<n;i++){	//先看内循环,根据题设模拟需要,每个学校依次进入;也就是学校循环在内; 
				if(j<num[i]){
					if(prei==i){ //如果前一个赋值的是同一个学校,间隔2,反之,则间隔1; 
						step+=2;//这里采取的还是人脑模拟,所以其实不用思考太多,直接抓住循环帮忙解决的赋值顺序,然后就好理解了; 
					}
					else step++;
					a[i][j][k]=step;
					prei=i; 
				}
			}
		}
	}
	for(i=0;i<n;i++){
		printf("#%d\n",i+1);		//output;
		for(j=0;j<num[i];j++){
			for(k=0;k<10;k++)
			{
				if(k!=9)
				printf("%d ",a[i][j][k]);
				else
				printf("%d",a[i][j][k]);
			}printf("\n");
		}
	}
    return 0;
}
### 天梯赛 L1-049 座位分配问题解析 天梯赛 L1-049 题目“座位分配”是一个考察队列操作与模拟逻辑的编程题。题目要求为多个学校的参赛队伍分配座位,确保同一学校的选手按照顺序入座,并且不同学校的选手不能相邻。当只剩下一个学校的选手时,需要隔位就坐。 #### 题目核心逻辑 1. **输入处理**: - 输入包含多个学校的队伍数量,每个学校每队有 10 名选手。 - 需要将所有选手按照顺序分配座位座位编号从 1 开始。 2. **队列模拟**: - 每个学校的所有选手应排成一列纵队。 - 各校的第 1 位选手依次入座,然后是第 2 位,依此类推。 - 当只剩下一个学校时,该学校的剩余选手必须隔位就坐。 3. **输出要求**: - 每个选手的座位号按学校和队伍顺序输出。 #### 算法实现思路 可以使用一个**队列数组**来模拟每个学校的选手队列。具体步骤如下: 1. **初始化队列**: - 每个学校建立一个队列,队列中依次加入该学校所有队伍的选手(每队 10 人)。 2. **模拟分配过程**: - 使用一个循环,每次从每个学校的队列中取出一个选手进行分配- 如果某个学校的队列为空,则跳过。 - 如果只剩下一个非空队列,则开始“隔位就坐”模式。 3. **座位编号处理**: - 座位号从 1 开始递增。 - 在“隔位就坐”模式下,每次分配后跳过一个座位。 #### 示例代码 以下是一个基于上述逻辑的 C++ 实现示例: ```cpp #include <bits/stdc++.h> using namespace std; int main() { int n; cin >> n; vector<queue<int>> schools(n); int total = 0; for (int i = 0; i < n; ++i) { int m; cin >> m; for (int j = 0; j < m * 10; ++j) { schools[i].push(i + 1); // 标记学校编号 } total += m * 10; } vector<vector<int>> result(n); // 每个学校选手的座位号 int seat = 1; int remaining = n; while (total--) { bool hasPlayer = false; for (int i = 0; i < n; ++i) { if (!schools[i].empty()) { hasPlayer = true; if (remaining > 1) { result[i].push_back(seat++); schools[i].pop(); } else { result[i].push_back(seat); schools[i].pop(); seat += 2; // 隔位就坐 } } } if (hasPlayer) { remaining = 0; for (int i = 0; i < n; ++i) { if (!schools[i].empty()) remaining++; } } } for (int i = 0; i < n; ++i) { for (int j = 0; j < result[i].size(); ++j) { cout << result[i][j] << " "; } cout << endl; } return 0; } ``` #### 关键点说明 - **队列管理**:使用 `queue` 结构管理每个学校的选手队列,便于模拟“先进先出”的分配逻辑。 - **隔位就坐**:当只剩一个学校未分配完时,使用 `seat += 2` 实现隔位就坐。 - **输出格式**:按照学校顺序输出每个选手的座位号。 #### 总结 L1-049 是一个典型的模拟题,考察的是对队列、循环控制和条件判断的综合运用。掌握这种类型的题目有助于提升编程思维和算法设计能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值