2021中兴捧月神算师算法赛,4-24第一场,第四题:D-换队伍,2021-4-28

第四题:D-换队伍

在这里插入图片描述
在这里插入图片描述

分析:
1.问题本身很简单,也只有两条队伍,一个队伍中的人换到另一个队伍的末尾。问题在于对其他人排队位置的保存和排序。
2.用什么数据结构进行保存,是一个很关键的问题,对问题解决的方法和时间复杂度都有很大关系。如果使用简单的数组,那么每执行一次换队伍,会需要对后面的人进行前移一个位置,那么时间复杂度就上升了。
3.很显然,一看到题,第一个想法就是链表,使用两个链表分别表示两个队伍,每个人作为链表的一个结点。当执行换队伍操作时,从一个链表中删除一个结点然后加到另一个链表末尾。这个方法是可行的,但是由于只有两个队伍,因此还可以采取更直接的方法。比如直接用一个map,将第i个人映射到{队伍0或1,在队伍中序号}这样的映射对中。
4.题目中保证了给的序号是正常的(不会超限),因此不需要进行序号判断可以直接进行换队伍。且保证队伍一定会有一个人。
5.注意n1,n2最大为10^5,因此一共最多可以有2x10 ^5 个人。
6.还有一个问题,为什么不直接用两个数组来表示队伍,换队伍时在原位置置0,在另一个队伍末尾赋值人员编号。这样在每个人只换一次队伍时是简单办法,但是如果某人换两次队伍,就会存在找不到这个人的问题,这也是需要考虑的
7.如果使用链表,要注意链表末尾结点要不同处理,判断下一结点是否指向NULL。

代码:
下面以别人提交的方案进行理解,来源均注明

方案1:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=47614394

这个方案是代码量小。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5;
int n1,n2,q;
int a[2][N*3],cnt[2];
int pos[N*2];
int main(){
   
    cin>>n1>>n2>>q;
    for(int i=1;i<=n1;i++){
   
        a[0][i]=i;
        pos[i]=i;      //给队伍1的每个人赋值序号,pos存储位置
    }
    for(int i=1;i<=n2;i++){
   
        a[1][i]=i+n1;
        pos[i+n1]=N*10+i; 
   //同理,给队伍2同样操作,但是把位置赋值 10N+i,避免与队伍1 的位置重复
    }
    cnt[0]=n1,cnt[1]=n2;   //对两个队伍的人数 计数
      
    for(int i=1;i<=q;i++){
        
        int x;
        cin>>x;
        if(pos[x]<N*
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值