L1-049 天梯赛座位分配(新解法,详细注释)

本文介绍了一种新的解题方法,将高校队伍座位分配问题视为等差数列,通过计算首项和公差,快速确定每个队伍在序列中的位置,从而实现高效排序。作者提供了C++代码实现并详细注释了过程。
摘要由CSDN通过智能技术生成

L1-049 天梯赛座位分配(新解法,详细注释)


一、题目分析

首先,题目意思还是比较好理解的,就是依次排位置,前面的高校先排,例如,我们有A、B、C三所高校,分别有若干支队伍,A1表示高校A的第一支队伍,A11表示高校A的第一支队伍的第一名队员的位置。
那么,座位安排如下:A11,B11,C11,A12…A21,B21,C21…
后面就是依次往后排了。

二、解题思路

我发现很多题解都是依次遍历,当然,我自己也尝试过,确实是可以做出来的。但我发现这道题是有一定规律的,类似于等差数列,把每支队伍看成一个等差数列,那么我们只需要知道每个数列的首项和公差即可。

三、代码实现

#include<bits/stdc++.h>
using namespace std;
#define pai pair<int,int>

const int N=110;
//m[i]表示第i所高校的队伍数
int m[N];
//用于存储每所高校的次序和队伍数:<次序,队伍数>
vector<pai> st;

int main(){
    int n;
    cin>>n;
    //初始化
    for(int i = 1;i <= n;i++){
        cin>>m[i];
        pai p(i,m[i]);
        st.push_back(p);
    }
    //根据队伍数,将st升序排序(采用拉姆达表达式书写自定义排序函数)
    sort(st.begin(),st.end(),[](pai a,pai b){ return a.second<b.second; });
    //依次输出每所高校队伍座位情况
    for(int i = 1;i <= n;i++){
        cout<<"#"<<i<<endl;
        //id表示当前座位,每所高校初始座位为i
        //k表示还未完全排完的高校数,初始化为n
        //v表示st的下标,指向还未排完的高校中队伍数最少的,初始化为0
        //dt表示第i所高校相邻队员所隔开的位置数,如果只有一所高校,则初始化为1,否则初始化为n
        int id = i,k = n,v = 0,dt = n==1? 2: n;
        //依次输出第i所高校的队伍座位表,x表示高校的第x支队伍
        for(int x = 1;x <= m[i];x++){
            for(int j = 1;j <= 10;j++){
                cout<<id;
                if(j != 10)cout<<' ';
                else puts("");
                id+=dt;
            }
            //当有高校所有队伍已经安排完了,dt需要更新(注意排位置是每所高校同步的)
            while(v < st.size()&&x == st[v].second){
                //队伍数-1
                k--;
                //如果不是只剩下当前一所高校,并且次序在前的高校所有队伍排完了,则当前高校的下一支队伍的第一个位置号要-1
                if(k != 1&&st[v].first < i)
                    id--;
                v++;
            }
            //更新dt,如果只有一所高校,dt=2,否则dt=k;
            dt = k==1? 2:k;
        }
    }
    return 0;
}
  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值