There are nn friends who want to give gifts for the New Year to each other. Each friend should give exactly one gift and receive exactly one gift. The friend cannot give the gift to himself.

For each friend the value fifi is known: it is either fi=0fi=0 if the ii-th friend doesn't know whom he wants to give the gift to or 1≤fi≤n1≤fi≤n if the ii-th friend wants to give the gift to the friend fifi.

You want to fill in the unknown values (fi=0fi=0) in such a way that each friend gives exactly one gift and receives exactly one gift and there is no friend who gives the gift to himself. It is guaranteed that the initial information isn't contradictory.

If there are several answers, you can print any.

大意是有n个人相互给礼物(限定一个人只能收到一份,赠送一份),已知其中一部分人希望把礼物送给谁,要求补全这个关系图,只需要输出任何一种可能的情况。其中不能自己送给自己礼物。
自己的暴力做法是:将所有人分成三类。第一类:有送有收。第二类:有送无收。第三类:无送有收。第四类:无送无收。
首先建立一个优先队列用于输出,第一类已经彻底明确了的直接丢进去。易知第二类和第三类人数应该是一样的,这时候讨论第四类:
1.若第四类人数为0:
只需要将第二类的收和第三类的送对应起来。一一对应即可。
2.若第四类人数为1:
第二类第三类前面n-1对一一对应,最后一对之间插一个唯一的第四类。(因为要求不能自己送自己)。
3.第四类人数大于1:
第四类内部对应即可,内部构成一个环。
#include<bits/stdc++.h>
using namespace std;
int n; struct point
{
int num;
int to;
int from;
}f[]; bool operator<(point a, point b){ return a.num>b.num ;} priority_queue<point> q;
vector<point> v1,v2,v3;//v1仅有from v2仅有to v3双无
int main()
{
cin>>n;
int i;
for(i=;i<=n;i++)
{
f[i].num=i;
f[i].to=;
f[i].from=;
} for(i=;i<=n;i++)
{
int temp;
scanf("%d",&temp);
f[i].to=temp;
f[temp].from=i;
} for(i=;i<=n;i++)
{
if(f[i].from!=&&f[i].to!=)
{
q.push(f[i]);
}
else if(f[i].from==&&f[i].to!=)
{
v2.push_back(f[i]);
}
else if(f[i].from!=&&f[i].to==)
{
v1.push_back(f[i]);
}
else
{
v3.push_back(f[i]);
}
} //cout<<v1.size()<<' '<<v2.size()<<' '<<v3.size()<<' '<<q.size()<<endl; if(v3.size()!=)
{
for(i=;i<v2.size();i++)
{
v2[i].from=v1[i].num;
v1[i].to=v2[i].num;
q.push(v1[i]);
q.push(v2[i]);
}
if(v3.size()==)goto label;
for(i=;i<v3.size()-;i++)//注意 不能自己给自己
{
v3[i].to=v3[i+].num;
q.push(v3[i]); }
v3[v3.size()-].to=v3[].num;
q.push(v3[v3.size()-]);
}
else
{
for(i=;i<v2.size()-;i++)
{
v2[i].from=v1[i].num;
v1[i].to=v2[i].num;
q.push(v1[i]);
q.push(v2[i]);
}
v2[v2.size()-].from=v3[].num;
v1[v2.size()-].to=v3[].num;
v3[].to=v2[v2.size()-].num;
q.push(v1[v2.size()-]);
q.push(v2[v2.size()-]);
q.push(v3[]); }
label:;
while(!q.empty())
{
point temp=q.top();
cout<<temp.to<<' ';
q.pop();
} return ;
}
 
 

Codeforces Round #611 (Div. 3) C的更多相关文章

  1. Codeforces Round #611 (Div. 3) A-F简要题解

    contest链接:https://codeforces.com/contest/1283 A. Minutes Before the New Year 题意:给一个当前时间,输出离第二天差多少分钟 ...

  2. Codeforces Round #611 (Div. 3)

    原题面:https://codeforces.com/contest/1283 A.Minutes Before the New Year 题目大意:给定时间,问距离零点零分还有多久? 分析:注意一下 ...

  3. Codeforces Round #611 (Div. 3) E

    Oh, New Year. The time to gather all your friends and reflect on the heartwarming events of the past ...

  4. Codeforces Round #611 (Div. 3) D

    There are nn Christmas trees on an infinite number line. The ii -th tree grows at the position xixi ...

  5. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  6. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  7. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  8. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  9. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

随机推荐

  1. C# 选取本月周六日方法

    用于工作: 1.取本月第一天就是1号 2.取下月第一天再减去一天 就是本月最后一天 3.从月头遍历至月末,判断周几 代码如下: #region 提取本月周六日 DateTime start = new ...

  2. C. Polygon for the Angle 几何数学

    C. Polygon for the Angle 几何数学 题意 给出一个度数 ,问可以实现的最小的n的n边形是多少 思路 由n边形的外角和是180度直接就可以算出最小的角是多少 如果给出的度数是其最 ...

  3. python 序列 倒着取元素

    当要倒着取元素时,用s[-2]只能取一个, 如果取多个时用s[-9:-1],注意,最后一个-1是不取出来的. 此时要用s[-9:] 最后一个空着就可以取出来了.

  4. jmeter的使用---录制脚本

    1.设置fidder 2.在fidder中导出请求,选择jmx格式

  5. 7_1 除法(UVa725)<选择合适的枚举对象>

    如果把数字0到9分配成2个整数(各五位数),现在请你写一支程序找出所有的配对使得第一个数可以整除第二个数,而且商为N(2<=N<=79),也就是:abcde / fghijk = N这里每 ...

  6. Text Infilling解读

    多头自注意力token解码器,该解码器能够对过去和未来的信息进行condition处理,适合填充任务:自注意力机制尤其适合填充文本,因为它可以为每个空白处从左到右及从右到左双向建模,为全部语义进行有效 ...

  7. Go非缓冲/缓冲/双向/单向通道

    1. 非缓冲和缓冲 package main import ( "fmt" "strconv" ) func main() { /* 非缓冲通道:make(ch ...

  8. iso15693芯片读写工具套件 icode-slix2读写 nfc type 5 tag读写

    iso15693芯片读写工具套件 icode-slix2读写 nfc type 5 tag读写校验套件 iso15693工具套件支持icode-slix,icode-slix2芯片的读写,支持iso1 ...

  9. Dart语言学习(五)Dart Bool类型

    Dart Bool类型和其他语言类似,比较简单 其特点有: 1.使用 bool 表示布尔类型 2.布尔值只有 true 和 false 3.布尔类型bool默认值是null bool isTrue = ...

  10. 5.Python语句

    .button, #logout { color: #333; background-color: #fff; border-color: #ccc; } span#login_widget > ...