CodeForces - 441D: Valera and Swaps(置换群)
A permutation p of length n is a sequence of distinct integers p1, p2, ..., pn (1 ≤ pi ≤ n). A permutation is an identity permutation, if for any i the following equation holds pi = i.
A swap (i, j) is the operation that swaps elements pi and pj in the permutation. Let's assume that f(p) is the minimum number of swaps that you need to make the permutation p an identity permutation.
Valera wonders, how he can transform permutation p into any permutation q, such that f(q) = m, using the minimum number of swaps. Help him do that.
The first line contains integer n (1 ≤ n ≤ 3000) — the length of permutation p. The second line contains n distinct integers p1, p2, ..., pn (1 ≤ pi ≤ n) — Valera's initial permutation. The last line contains integer m (0 ≤ m < n).
Output
In the first line, print integer k — the minimum number of swaps.
In the second line, print 2k integers x1, x2, ..., x2k — the description of the swap sequence. The printed numbers show that you need to consecutively make swaps (x1, x2), (x3, x4), ..., (x2k - 1, x2k).
If there are multiple sequence swaps of the minimum length, print the lexicographically minimum one.
Examples
5
1 2 3 4 5
2
2
1 2 1 3
5
2 1 4 5 3
2
1
1 2
Note
Sequence x1, x2, ..., xs is lexicographically smaller than sequence y1, y2, ..., ys, if there is such integer r (1 ≤ r ≤ s), that x1 = y1, x2 = y2, ..., xr - 1 = yr - 1 and xr < yr.
题意:有函数f(p),表示把排列p,变为顺序的排列,所用的最小交换次数,这里的交换是两两交换,而不是相邻交换。
现在给你排列p和m,让你交换最小的次数,使得排列变为q,满足f(q)=m,如果有多种交换方案,输出字典序最小的;
思路:1,把排列p变为1,2,3....p,的最小次数=N-环数。假如N-环数<m,那就加环。 否则减环。
2,如果交换两个不在同一个环的位置的数,那么环数+1;
3,如果交换在同一个环的位置的数,那么环数-1;
所以我们的任务就是加环或者减环,而每次分组的复杂度是O(N);我们最多加N次环,所以我们可以暴力交换,交换后重新分组。
复杂度O(N^2);
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int a[maxn],vis[maxn],tot,N,M;
void dfs(int u)
{
if(vis[u]) return ;
vis[u]=tot;
dfs(a[u]);
}
void rebuild()
{
tot=; rep(i,,N) vis[i]=;
rep(i,,N) if(!vis[i]) tot++,dfs(i);
}
int main()
{
scanf("%d",&N);
rep(i,,N) scanf("%d",&a[i]);
rebuild();
scanf("%d",&M);
if(M==N-tot) return puts(""),;
int ans,opt=;
if(M>N-tot) ans=M-N+tot,opt=; //合
else ans=N-tot-M;//拆
printf("%d\n",ans);
rep(i,,N)
rep(j,,N){
if(!ans) break;
if(i!=j&&(abs(vis[i]-vis[j])?:)==opt) {
swap(a[i],a[j]); ans--;
printf("%d %d ",i,j);
rebuild();
}
}
return ;
}
CodeForces - 441D: Valera and Swaps(置换群)的更多相关文章
- Codeforces 441D Valera and Swaps(置换群)
题意: 给定一个1~n的排列(n<=3000),输出字典序最小且次数最少的交换操作,使得操作后的排列可以通过最少m次交换得到排列[1,2,...n] Solution: 可以将排列的对应关系看做 ...
- CF(441D Valera and Swaps)置换群
题意:1-n的一个排列, p2, ..., pn,f(p)的定义是此排列要交换最少的数对能够回到原排列1,2,3,4...n.给一个排列p.要将其变换成f值为m的排列,问至少要交换几个数对,并输出字典 ...
- [codeforces 339]E. Three Swaps
[codeforces 339]E. Three Swaps 试题描述 Xenia the horse breeder has n (n > 1) horses that stand in a ...
- Codeforces 441C Valera and Tubes
题目链接:Codeforces 441C Valera and Tubes 没看到r >= 2一直错.让前几个管子占用2个格子.最后一个把剩下的都占用了.假设问题有解.这样做一定有解.其它策略就 ...
- CodeForces - 369E Valera and Queries(树状数组)
CodeForces - 369E Valera and Queries 题目大意:给出n个线段(线段的左端点和右端点坐标)和m个查询,每个查询有cnt个点,要求给出有多少条线段包含至少其中一个点. ...
- Educational Codeforces Round 14 D. Swaps in Permutation 并查集
D. Swaps in Permutation 题目连接: http://www.codeforces.com/contest/691/problem/D Description You are gi ...
- codeforces 441B. Valera and Fruits 解题报告
题目链接:http://codeforces.com/problemset/problem/441/B 题目意思:有 n 棵fruit trees,每课水果树有两个参数描述:水果成熟的时间和这棵树上水 ...
- Codeforces 425A Sereja and Swaps(暴力枚举)
题目链接:A. Sereja and Swaps 题意:给定一个序列,能够交换k次,问交换完后的子序列最大值的最大值是多少 思路:暴力枚举每一个区间,然后每一个区间[l,r]之内的值先存在优先队列内, ...
- codeforces B. Valera and Contest 解题报告
题目链接:http://codeforces.com/problemset/problem/369/B 题目意思:给出6个整数, n, k, l, r, sall, sk ,需要找出一个满足下列条件的 ...
随机推荐
- redis使用epoll
redis使用epoll的代码在ae_epoll.c文件中. epoll_create:redis服务器在启动时,创建事件循环,调用epoll_create方法创建epoll实例. static in ...
- Tomcat禁用SSLv3和RC4算法
1.禁用SSLv3(SSL 3.0 POODLE攻击信息泄露漏洞(CVE-2014-3566)[原理扫描]) 编缉$CATALINA_HOEM/conf/server.xml配置文件,找到https端 ...
- 微服务之SpringCloud基础
SpringCloud微服务基础 微服务架构--SpringCloud网站架构模式 单点应用/分布式系统面向于服务架构(SOA) /微服务架构web项目三层架构1.控制层2.业务逻辑层3.数据访问层传 ...
- 《Java面向对象编程》
<Java面向对象编程> 第11章 对象的生命周期 11.1 创建对象的方式 用new语句创建对象 运用反射手段,调用java.lang.Class 或者 java.lang.Const ...
- 认识微软Visual Studio Tools for AI
认识微软Visual Studio Tools for AI 微软已经发布了其 Visual Studio Tools for AI 的测试版本,这是微软 Visual Studio 2017 I ...
- WPF 之 TreeView节点重命名
下面的TreeView节点是通过数据双向绑定的方式,绑定到TextBlock控件和TextBox控件的Text属性上,并且让两者绑定相同的属性,同时使TextBox控件刚好完全覆盖TextBlock控 ...
- unity中键盘WASD控制。(WS控制物体前后移动,AD控制左右旋转。)
private float rotateSpeed = 30f; private float movespeed = 5; void FixedUpdate() { //第一种控制移动 float h ...
- 过滤器 拦截器 登录login实例
当请求来的时候,首先经过拦截器/过滤器,在经过一系列拦截器/拦截器处理后,再由再根据URL找到Servlet.执行servlet中的代码. 过滤器:按照过滤的对象类型的不同,可分为按资源名过滤和按请求 ...
- springMVC的工作流程图
- cxf http 代码自动生成
1.下载 cxf 直接进入镜像下载http://mirrors.tuna.tsinghua.edu.cn/apache/cxf/3.1.12/apache-cxf-3.1.12.zip 2.配置 CX ...