题意:n个人要把自己手上的礼物送给其他人,一不能送给自己,二礼物必须精确地送给别人。其中fi表示第i个人把自己的礼物送给了第fi个人,0表示还没送。输出一个可能的fi序列。
思路:我们手动模拟一下会发现,我们只需要保证还没送出礼物的人把礼物送给别人就行了,但是题目的难点在于自己的礼物很容易送给自己。所以一个最简单的思路就是先将那些没有收到礼物且自己也没有送出的这些人,把礼物送给下一个没有收到礼物的人,从而保证不会出现上述情况。
#include <bits/stdc++.h> using namespace std; set<int>s,sb; vector<int>tmp; int n; int x[200005]; int main(){ int Ji = 0, Ou = 0; scanf("%d",&n); for(int i = 1; i <= n; i++){ scanf("%d",&x[i]); if(x[i] == 0) tmp.push_back(i); else sb.insert(x[i]); } for(int i = 1; i <= n; i++) if(sb.count(i) == 0) s.insert(i); int Size = tmp.size(); for(int i = 0; i < Size; i++){ //printf("tmp[%d]:%d\n",i,tmp[i]); if(s.count(tmp[i]) == 1){ x[tmp[(i+1)%Size]] = tmp[i]; s.erase(tmp[i]); } } for(int i = 1; i <= n; i++){ if(x[i] == 0) for(auto Num : s){ x[i] = Num; s.erase(Num); break; } } for(int i = 1; i <= n; i++) printf("%d ",x[i]); return 0; }
原文:https://www.cnblogs.com/LYFer233/p/12601683.html