前言
话说没想到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的空间复杂度。