D - Swap Pass

先将所有\(a_i==i\)的点都直接去掉

考虑将\(i\)向\(a_i\)连边,那么就会形成一个个的环

考虑只有一个环的情况,那么我们任意固定一个点\(x\),一直交换\(a_x\)与\(a_{a_x}\)直到\(a_x==x\),因为所有所有边都交于一点,所以这肯定是合法的

但更普遍的情况是不止有一个环,那么我们考虑交换两个环之间的某两个点的\(a\),那么这样就可以将两个环合成一个大环,然后继续我们刚才的操作即可

但是有可能环与环之间的边与大环里连的边相交了,考虑如何解决

我们选择最左边的最下的点作为极点\(O\),然后将其余点根据极角排序

我们用相邻点连边来解决环与环之间的交换,这个可以用并查集维护

然后从极点进行大环的连边,这样显然不存在相交的边

#include<bits/stdc++.h>
#define pii pair<int,int>
#define pb push_back
using namespace std;
const int N=2e3+5;
struct node{
int x,y,a,id;
double angle;
bool operator < (const node &other) const{
return angle<other.angle;
}
}cn[N];
int n,tot,fa[N],to[N];
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
void merge(int x,int y){
x=find(x),y=find(y);
fa[x]=y;
}
vector<pii> op;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
++tot,scanf("%d%d%d",&cn[tot].x,&cn[tot].y,&cn[tot].a),cn[tot].id=i;
if(cn[tot].a==i) --tot;
fa[i]=i;
}
if(tot==0) return puts("0"),0;
n=tot;
int st=1;
for(int i=2;i<=n;++i) if(cn[i].x<cn[st].x||(cn[i].x==cn[st].x&&cn[i].y<cn[st].y)) st=i;
swap(cn[1],cn[st]);
for(int i=2;i<=n;++i) cn[i].angle=atan2(cn[i].x-cn[1].x,cn[i].y-cn[1].y);
sort(cn+2,cn+n+1);
for(int i=1;i<=n;++i) merge(cn[i].id,cn[i].a);
for(int i=2;i<n;++i){
int a=find(cn[i].id),b=find(cn[i+1].id);
if(a!=b) merge(a,b),swap(cn[i].a,cn[i+1].a),op.pb({cn[i].id,cn[i+1].id});
to[cn[i].id]=i;
}
to[cn[1].id]=1,to[cn[n].id]=n;
while(cn[1].a!=cn[1].id){
int t=to[cn[1].a];
swap(cn[1].a,cn[t].a),op.pb({cn[1].id,cn[t].id});
}
printf("%d\n",op.size());
for(auto [x,y]:op) printf("%d %d\n",x,y);
return 0;
}

[CF1508D] Swap Pass的更多相关文章

  1. Swap in C C++ C# Java

    写一个函数交换两个变量的值. C: 错误的实现: void swap(int i, int j) { int t = i; i = j; j = t; } 因为C语言的函数参数是以值来传递的(pass ...

  2. c/c++和java达到swap不同功能

    首先我们来看看c/c++实施swap性能 void swap ( int & a, int & b) { int Temp; temp = a; a = b; b = temp; } ...

  3. 搞定C系语言的的swap

    http://www.cs.utsa.edu/~wagner/CS2213/swap/swap.html 原地址 Parameters, by value and by reference: Both ...

  4. 非阻塞同步算法与CAS(Compare and Swap)无锁算法

    锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放. ...

  5. 63. Swap Nodes in Pairs && Rotate List && Remove Nth Node From End of List

    Swap Nodes in Pairs Given a linked list, swap every two adjacent nodes and return its head. For exam ...

  6. Bus Pass

    ZOJ Problem Set - 2913 Bus Pass Time Limit: 5 Seconds      Memory Limit: 32768 KB You travel a lot b ...

  7. swap分析及其使用

    什么是swap swap主要是在内存不够用的时候,将部分内存上的数据交换到swap空间上,以便让系统不会因为内存不够用而导致oom或者更致命的情况出现.当内存使用存在压力的时候,开始触发内存回收行为, ...

  8. 考虑实现一个不抛异常的swap

    Effective C++:参考自harttle land 类的swap实现与STL容器是一致的:提供swap成员函数, 并特化std::swap来调用那个成员函数. class Widget { p ...

  9. C++异常安全、copy and swap

    异常安全的代码是指,满足两个条件 1异常中立性 : 是指当你的代码(包括你调用的代码)引发异常时,这个异常 能保持原样传递到外层调用代码.(异常中立,就是指任何底层的异常都会抛出到上层,也就相当于是异 ...

  10. Linux临时增加swap空间

    linux临时增加swap空间:step 1: #dd if=/dev/zero of=/home/swap bs=1024 count=500000 注释:of=/home/swap,放置swap的 ...

随机推荐

  1. SQL Server 5105 和 1802 错误的触发方式和解决方式之一

    一般导致这两个错误的原因是:文件路径错误 还有的说,可能是文件权限问题,详情见权限错误纠正方式 错误代码 create database teaching on primary ( name = te ...

  2. 推荐Linux命令行运维工具: Wowkey--实现自动化批量化标准化

    WowKey命令行运维工具,Linux设备的自动化.批量化.标准化的运维解决方案,解放运维人,提升企业运维效率和质量. 有人能理解做设备的运营维护工作的痛苦所在吗? 如果你的运维工作中,只维护个位数数 ...

  3. PMP学习记录

    本人在2020年12月已经顺利拿到PMP证书. 第一次听说PMP证书是2016年,一个同事说考试通过拿到了PMP证书,当时对PMP不是很了解.也未作深入了解,当时认为俺是做技术的,这个证书没啥用.O( ...

  4. 解决VSCODE进行C代码编辑时结构体成员不可见或不提示的问题

    在使用VSCODE进行C代码编辑时,结构体成员有时可见,光标放到成员上时,系统会提示结构体成员对应的注释信息,但是有时候却不行. 经过测试,发现有如下规律:以test.c test.h include ...

  5. Sql查询(Select)语句实例

    span { color: rgba(255, 0, 0, 1) } Select 结构: 句子结构: Select 列名 [all/distinct] from 表名 where 条件 group ...

  6. Java+Appium+Junit实现app自动化demo

    1.新建maven工程和引入库 步骤参考https://www.cnblogs.com/wanyuan/p/16408758.html 2.编写代码 代码如下: import org.junit.Af ...

  7. Git的基础使用(一)

    Git版本管理工具的作用: (1)完整的记录项目代码变化的过程 (2)备份每一个变化过程的代码版本 (3)多人协同开发 1.配置全局变量 (1)配置用户名 git config --global us ...

  8. 刷题——关于struts框架,下面那些说法是正确的?

    关于struts框架,下面那些说法是正确的? Struts中无法完成上传功能 Struts框架基于MVC模式 Struts框架容易引起流程复杂.结构不清晰等问题 Struts可以有效地降低项目的类文件 ...

  9. 【命令详解001】top

    top命令可以用于实时监控cpu的状态,显示系统中各个进程的资源占用情况. 本次来详细看下top命令. 常用命令示例: top # 对,无参数的top命令是最长用的资源监控命令. [root@VM_0 ...

  10. CV中常用Backbone-2:ConvNeXt模型详解及其代码

    之前介绍了CV常用Backbon: CV中常用Backbone-1:Resnet/Unet/Vit系列/多模态系列等)以及代码 这里介绍新的一个Backbone:ConvNeXt,主要来自两篇比较老的 ...