其他分享
首页 > 其他分享> > CF1530 D. Secret Santa(模拟+思维)

CF1530 D. Secret Santa(模拟+思维)

作者:互联网

目录

Description

有 \(n\) 个数,表示 \(i\) 想要把礼物送给 \(a[i]\), 问最后最多有几个人可以将礼物送给对的人,不可以将礼物送给自己

State

\(1<=t<=10^5\)

\(2<=n<=2*10^5\)

\(1<=a[i]<=n,\ a[i] \neq i\)

Input

2
3
2 1 2
7
6 4 6 2 4 5 6

Output

2
3 1 2
4
6 4 7 2 3 5 1

Solution

这道题目想不过来,把数带进去更容易码出来

先看一下样例二,发现 \(6,\ 4\) 出现多次,假设 \(3,\ 5,\ 7\) ,还未将礼物送出,而 \(1,\ 3,\ 7\) 还没有收到礼物,这样依次匹配的话,\(7\) 送不出礼物,但是 \(7\) 原来想要送给 \(6\),这样 \(7\) 送给 \(6\),再让 \(1\) 送给 \(7\),答案的最大值还是没有变

Code

const int N = 2e5 + 5;

    ll n, m, _;
    int i, j, k;
    ll a[N];
    int vis[N];
    int mach[N];

signed main()
{
    //IOS;
    rush(){
        sd(n);
        rep(i, 1, n){
            sd(a[i]);
            vis[i] = 0;
            mach[i] = 0;
        }
        int ans = 0;
        rep(i, 1, n){
            if(vis[a[i]]) continue;
            vis[a[i]] = i;
            mach[i] = a[i];
            ans ++;
        }
        pd(ans);
        vector<int> res;
        rep(i, 1, n){
            if(vis[i] == 0) res.pb(i); 
        }
        int p = 1;
        for(auto it : res){
            while(mach[p]) p ++;
            mach[p] = it;
            if(p == it){
                swap(mach[p], mach[vis[a[p]]]);
                vis[a[p]] = p;
            }
        }
        for(int i = 1; i <= n; i ++){
            printf("%d ", mach[i]);
        }
        puts("");
    }
    //PAUSE;
    return 0;
}

标签:CF1530,int,vis,Secret,Santa,ans,送给,礼物,mach
来源: https://www.cnblogs.com/Segment-Tree/p/15185025.html