[CF1508D] Swap Pass
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的更多相关文章
- Swap in C C++ C# Java
		
写一个函数交换两个变量的值. C: 错误的实现: void swap(int i, int j) { int t = i; i = j; j = t; } 因为C语言的函数参数是以值来传递的(pass ...
 - c/c++和java达到swap不同功能
		
首先我们来看看c/c++实施swap性能 void swap ( int & a, int & b) { int Temp; temp = a; a = b; b = temp; } ...
 - 搞定C系语言的的swap
		
http://www.cs.utsa.edu/~wagner/CS2213/swap/swap.html 原地址 Parameters, by value and by reference: Both ...
 - 非阻塞同步算法与CAS(Compare and Swap)无锁算法
		
锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放. ...
 - 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 ...
 - Bus Pass
		
ZOJ Problem Set - 2913 Bus Pass Time Limit: 5 Seconds Memory Limit: 32768 KB You travel a lot b ...
 - swap分析及其使用
		
什么是swap swap主要是在内存不够用的时候,将部分内存上的数据交换到swap空间上,以便让系统不会因为内存不够用而导致oom或者更致命的情况出现.当内存使用存在压力的时候,开始触发内存回收行为, ...
 - 考虑实现一个不抛异常的swap
		
Effective C++:参考自harttle land 类的swap实现与STL容器是一致的:提供swap成员函数, 并特化std::swap来调用那个成员函数. class Widget { p ...
 - C++异常安全、copy and swap
		
异常安全的代码是指,满足两个条件 1异常中立性 : 是指当你的代码(包括你调用的代码)引发异常时,这个异常 能保持原样传递到外层调用代码.(异常中立,就是指任何底层的异常都会抛出到上层,也就相当于是异 ...
 - Linux临时增加swap空间
		
linux临时增加swap空间:step 1: #dd if=/dev/zero of=/home/swap bs=1024 count=500000 注释:of=/home/swap,放置swap的 ...
 
随机推荐
- SQL Server 5105 和 1802 错误的触发方式和解决方式之一
			
一般导致这两个错误的原因是:文件路径错误 还有的说,可能是文件权限问题,详情见权限错误纠正方式 错误代码 create database teaching on primary ( name = te ...
 - 推荐Linux命令行运维工具: Wowkey--实现自动化批量化标准化
			
WowKey命令行运维工具,Linux设备的自动化.批量化.标准化的运维解决方案,解放运维人,提升企业运维效率和质量. 有人能理解做设备的运营维护工作的痛苦所在吗? 如果你的运维工作中,只维护个位数数 ...
 - PMP学习记录
			
本人在2020年12月已经顺利拿到PMP证书. 第一次听说PMP证书是2016年,一个同事说考试通过拿到了PMP证书,当时对PMP不是很了解.也未作深入了解,当时认为俺是做技术的,这个证书没啥用.O( ...
 - 解决VSCODE进行C代码编辑时结构体成员不可见或不提示的问题
			
在使用VSCODE进行C代码编辑时,结构体成员有时可见,光标放到成员上时,系统会提示结构体成员对应的注释信息,但是有时候却不行. 经过测试,发现有如下规律:以test.c test.h include ...
 - Sql查询(Select)语句实例
			
span { color: rgba(255, 0, 0, 1) } Select 结构: 句子结构: Select 列名 [all/distinct] from 表名 where 条件 group ...
 - Java+Appium+Junit实现app自动化demo
			
1.新建maven工程和引入库 步骤参考https://www.cnblogs.com/wanyuan/p/16408758.html 2.编写代码 代码如下: import org.junit.Af ...
 - Git的基础使用(一)
			
Git版本管理工具的作用: (1)完整的记录项目代码变化的过程 (2)备份每一个变化过程的代码版本 (3)多人协同开发 1.配置全局变量 (1)配置用户名 git config --global us ...
 - 刷题——关于struts框架,下面那些说法是正确的?
			
关于struts框架,下面那些说法是正确的? Struts中无法完成上传功能 Struts框架基于MVC模式 Struts框架容易引起流程复杂.结构不清晰等问题 Struts可以有效地降低项目的类文件 ...
 - 【命令详解001】top
			
top命令可以用于实时监控cpu的状态,显示系统中各个进程的资源占用情况. 本次来详细看下top命令. 常用命令示例: top # 对,无参数的top命令是最长用的资源监控命令. [root@VM_0 ...
 - CV中常用Backbone-2:ConvNeXt模型详解及其代码
			
之前介绍了CV常用Backbon: CV中常用Backbone-1:Resnet/Unet/Vit系列/多模态系列等)以及代码 这里介绍新的一个Backbone:ConvNeXt,主要来自两篇比较老的 ...