【数据结构】Codeforce 1283C Friends and Gifts

新的一年,继续开始啦!

一、题目大意

题目的大致意思是,有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;
}

如果有问题,欢迎大家指正!!!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值