U192222匹配(北大附中新春公开赛2022T4)


前言

话说没想到T4出了个模拟,(大雾 我觉得比赛难度应该是T1-T4-T3-T2吧,T4没有那么难。也可能是最近模拟做多了?


题目大意

题目有点长放个链接。题目传送门


思路

读了一下题就能看出是模拟了。做模拟可以在纸上过几遍样例,题读两到三遍,确保没拉下啥,之后调的时间可比多读几遍题多。

再没有达到条件前就一直循环。退出的条件题目里也说了,就是没有一个 h [ i ] = 0 h[i]=0 h[i]=0

之后没满足之前:
首先定义一个数组good g o o d [ i ] good[i] good[i] 为第 i i i 个人是否匹配成功,如果匹配了就跳过不发。再然后有一个数组num n u m [ i ] num[i] num[i] 为第 i i i 个人当前的选择公司。每一次 + 1 +1 +1,也就是上一次一定被拒绝了,没有匹配成功。之后就可以知道这一次选的公司是f[i][now[i],然后就去按照题意比较了。

注意:map的空间复杂度也要算算,为使用的空间大小,也就是 O ( []里的空间复杂度 ∗ 使用的元素个数 \mathcal{O}(\text{[]里的空间复杂度}*\text{使用的元素个数} O([]里的空间复杂度使用的元素个数,在本题里如果用 pair<ll,ll>表示公司和排名的话空间复杂度就是 O ( 16 n 2 ) \mathcal{O}(16n^2) O(16n2),开long long 就是大约400MB,MLE欢迎你。所以只能 O ( n ) \mathcal{O}(n) O(n) 查询排名了(悲伤)。在用map之前也要在空间复杂度那里算一下map的空间复杂度,或者时空间复杂度允许的条件下能不用map就不用。


代码

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const ll MAXN=5001;
ll f[MAXN][MAXN],g[MAXN][MAXN],now[MAXN],h[MAXN];//分别为f,g,每一个毕业生没被拒绝的位置,h
bool good[MAXN];//是否完成配对(包括暂时)
ll n,seed;
ll get_rank(ll k,ll i){
    for (int j = 1; j <=n ; ++j) {
        if(g[k][j]==i){
            return j;
        }
    }
    return 0;
}
int main(){
    cin>>n>>seed;
    srand(seed);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++) f[i][j] = j;
        random_shuffle(f[i]+1, f[i]+1+n);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++) g[i][j] = j;
        random_shuffle(g[i]+1, g[i]+1+n);
    }
    while (true){
        for (int i = 1; i <=n ; ++i) {
            //遍历所有员工
            if(good[i]){
                continue;
            }
            now[i]++;
            ll sent=f[i][now[i]];
            if(h[sent]==0){
                h[sent]=i;
            }else{
                if(get_rank(sent,h[sent])>get_rank(sent,i)){
                    h[sent]=i;
                }
            }
        }
        memset(good, false,sizeof(good));
        for (int i = 1; i <=n ; ++i) {
            if(h[i]){
                good[h[i]]= true;
            }
        }
        bool fin= true;
        for (int i = 1; i <=n ; ++i) {
            if(h[i]==0){
                fin= false;
                break;
            }
        }
        if(fin){
            break;
        }
    }
    for (int i = 1; i <=n ; ++i) {
        cout<<h[i]<<" ";
    }
    return 0;
}


总结

做了一道大模拟。同时知道了map的空间复杂度是存的东西的总大小,不要无视map的空间复杂度。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值