返回顶部

Codeforces Round #733 (Div. 1 + Div. 2, based on VK Cup 2021 - Elimination (Engine)) D. Secret Santa (构造,STL)

  • 题意:一共有\(n\)个人,每个人都要送礼物给别人,每个人都要收到礼物,但每个人都有自己相送的人,序列\(a\)表示第\(i\)个人想送礼物给\(a[i]\),输出长度为\(n\)的序列,表示\(i\)送礼物给\(b[i]\).

  • 题解:先用set将能给礼物的先给了,即将没收到礼物的\(a[i]\)先给了,给过就erase掉,并且记录答案和送他礼物的人\(i\)(后面有用).然后遍历所有人,如果这个人还没送,就取\(t\)中最靠前的人给他送掉,如果当前最靠前元素恰好是\(i\),如果\(t\)中元素不止一个就取第二靠前的元素,如果只剩一个,说明此时的\(i=n\)\(t\)中的元素也一定是\(n\),前面一定有一个\(a[j]=a[n]\),因为如果只有一个\(a[n]\)话,说明这个位置一定是合法的即我们之前就记录过了,所以\(a[n]\)一定出现了多次,这样我们记录的\(pos\)就派上用场了,直接和任意一个交换位置即可.

  • 代码:

    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
     
     
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    	int _;
    	cin>>_;
    	while(_--){
    		int n;
    		cin>>n;
    		vector<int> a(n+1);
    		set<int> s,t;
    		vector<int> pos(n+1);
    		rep(i,1,n){
    			cin>>a[i];
    			s.insert(a[i]);
    			t.insert(i);
    		}
    		cout<<(int)s.size()<<'\n';
    		vector<int> ans(n+1);
    		rep(i,1,n){
    			if(s.count(a[i])){
    				ans[i]=a[i];
    				s.erase(a[i]);
    				t.erase(a[i]);
    				pos[a[i]]=i;
    			}
    		}
    		rep(i,1,n){
    			if(ans[i]==0){
    				auto it=t.begin();
    				int x=*it;
    				t.erase(x);
    				if(x==i){
    					if(t.empty()){
    						ans[pos[a[i]]]=x;
    						ans[i]=a[i];
    						pos[a[i]]=i;
    					}
    					else{
    						auto itt=t.begin();
    						int xx=*itt;
    						ans[i]=xx;
    						t.erase(xx);
    						t.insert(x);
    					}
    				}
    				else{
    					ans[i]=x;
    				}
    			}
    		}
    		rep(i,1,n) cout<<ans[i]<<' ';
    		cout<<'\n';
    	}
    	
        return 0;
    }
    
posted @ 2021-07-25 16:35  Rayotaku  阅读(96)  评论(0编辑  收藏  举报