新的一年,继续开始啦!
一、题目大意
题目的大致意思是,有n个朋友要送礼物,每个人只能送一个礼物并且同时接受一个礼物,现在给出一个f数组,其中 fi 表示要送礼物给的编号(1~n),若 fi为0,则表示暂时还没有决定送给谁。
要求你在给定 f 数组的基础上,决定每个朋友要把礼物送给谁才能保证上面的条件?
二、题目思路以及AC代码
我一开始先蹦出来的思路是dfs,这很明显可以用dfs求解,但是我看到数据范围就觉得不可行,一般dfs的时候,n在几十到一百的时候就已经撑死了,这道题给的数据范围是2e5,不能用dfs,当然我还是抱着试一试的态度试了试,结果TLE。
然后就考虑,本题其实没有那么复杂,就是f数组有几个未知的数要你填上,而且要满足这几个数和其对应下标不相等,那么我们就可以考虑定义两个数组,一个是nums,存储还没有被送礼物的标号,一个是zeros,存储还不知道把礼物送给谁的标号,然后只需要调整这其中一个数组,使这两个数组同一索引的数字不同即可,这样所有的循环的时间复杂度就是O(n)了。
下面给出AC代码:
/*
* Codeforce 1283C
* @ Author: Johnson
* @ Date: 2019.12.31
*/
#include <iostream>
#define MAXN 200010
using namespace std;
int f[MAXN];
int zeros[MAXN];
int nums[MAXN];
bool vis[MAXN];
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int n;
cin >> n;
int zeros_idx = 0;
for (int i=1;i<=n;i++) {
cin >> f[i];
if (f[i]) vis[f[i]] = true;
else zeros[zeros_idx++] = i;
}
int nums_idx = 0;
for (int i=1;i<=n;i++) {
if (!vis[i]) nums[nums_idx++] = i;
}
for (int i=0;i<zeros_idx;i++) {
if (nums[i] == zeros[i]) {
swap(zeros[i], zeros[zeros_idx - 1]);
}
}
if (nums[zeros_idx - 1] == zeros[zeros_idx - 1]) swap(zeros[0], zeros[zeros_idx - 1]);
for (int i=0;i<zeros_idx;i++) {
f[zeros[i]] = nums[i];
}
for (int i=1;i<=n;i++) {
cout << f[i] << " ";
}
cout << endl;
// system("pause");
return 0;
}
如果有问题,欢迎大家指正!!!