CF(441D Valera and Swaps)置换群
题意:1-n的一个排列 p1, p2, ..., pn,f(p)的定义是此排列要交换最少的数对能够回到原排列1,2,3,4...n。给一个排列p。要将其变换成f值为m的排列,问至少要交换几个数对,并输出字典序最小的那组答案。
解法:处理出全部的置换群,求出环数k,此时f值为n-k。然后推断n-k和m的大小,分为两种操作
1、加环,这个是在随意元素个数大于1的环内交换随意两个数都能够做到加环
2、减环,交换随意两个环的随意两个元素。就能够做到将两个环连接起来
题目要求是输出字典序最小,那么就暴力搞。
代码:
/******************************************************
* author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
//freopen ("in.txt" , "r" , stdin);
using namespace std; #define eps 1e-8
#define zero(_) (abs(_)<=eps)
const double pi=acos(-1.0);
typedef long long LL;
const int Max=3010;
const int INF=1000000007; vector<int> vec[Max];
int all=0;
int num[Max];
bool rem[Max];
int m;
int n;
int yinggai;
void make(int t)
{
if(rem[t])
return ;
rem[t]=1;
vec[all].push_back(t);
make(num[t]);
}
struct point
{
int p1,p2;
} points[Max];
bool operator<(point a,point b)
{
if(a.p1!=b.p1)
return a.p1<b.p1;
return a.p2<b.p2;
}
void solve()
{
all=0;
memset(rem,0,sizeof rem);
vec[0].clear();
for(int i=1; i<=n; i++)
{
if(!rem[i])
make(i),all++,vec[all].clear();
}
for(int i=0; i<all; i++)
sort(vec[i].begin(),vec[i].end());
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",num+i);
solve();
yinggai=n-all;
//cout<<" "<<yinggai<<endl;
scanf("%d",&m);
cout<<abs(yinggai-m)<<endl;
if(m>yinggai)
{
vector<int> help;
for(int i=0; i<all; i++)
{
if(vec[i][0]!=1)
help.push_back(vec[i][0]);
}
sort(help.begin(),help.end());
bool b=1;
printf("1 %d",help[0]);
for(int i=1; i<m-yinggai; i++)
printf(" 1 %d",help[i]);
cout<<endl;
}
else if(m<yinggai)
{
int t=yinggai-m;
//cout<<"fdas";
for(int i=0;i<t;i++)
{
solve();
pair<int,int > p(Max,Max);
for(int i=0;i<all;i++)
{
if(vec[i].size()>1&&vec[i][0]<p.first)
{
p.first=vec[i][0];
p.second=vec[i][1];
}
}
swap(num[p.first],num[p.second]);
if(i==0)
printf("%d %d",p.first,p.second);
else
printf(" %d %d",p.first,p.second);
}
}
return 0;
}
CF(441D Valera and Swaps)置换群的更多相关文章
- Codeforces 441D Valera and Swaps(置换群)
题意: 给定一个1~n的排列(n<=3000),输出字典序最小且次数最少的交换操作,使得操作后的排列可以通过最少m次交换得到排列[1,2,...n] Solution: 可以将排列的对应关系看做 ...
- CodeForces - 441D: Valera and Swaps(置换群)
A permutation p of length n is a sequence of distinct integers p1, p2, ..., pn (1 ≤ pi ≤ n). A permu ...
- CF 369C . Valera and Elections tree dfs 好题
C. Valera and Elections The city Valera lives in is going to hold elections to the city Parliament ...
- CF 441E Valera and Number
CF 441E Description 一共执行\(k\)次,每次有\(p\%\)把\(x * 2\),有\((100 - p)\%\)把\(x + 1\).问二进制下\(x\)末尾期望\(0\)的个 ...
- Valera and Swaps
题意: 定义 $f(p)$ 表示将 $p$ 序列变换为有序序列最少要交换多少次,给一 $1 \sim n$ 的排列 $a$ ,给一整数 $m$, 求问将 $a$ 最少交换多少次能得到 $p$ ,使得 ...
- cf E. Valera and Queries
http://codeforces.com/contest/369/problem/E 题意:输入n,m; n 代表有多少个线段,m代表有多少个询问点集.每一个询问输出这些点的集合所占的线段的个数. ...
- cf D. Valera and Fools
http://codeforces.com/contest/369/problem/D 标号最小的两个人会有四种状态:a活b活,a死b活,a活b死,a死b死:按照这四种状态dfs就可以求出最后的数量. ...
- cf C. Valera and Elections
http://codeforces.com/contest/369/problem/C 先见边,然后dfs,在回溯的过程中,如果在这个点之后有多条有问题的边,就不选这个点,如果没有而且连接这个点的边还 ...
- cf B. Valera and Contest
http://codeforces.com/contest/369/problem/B 先对k个处理,先处理sk%k个为sk/k+1,如果sk/k==0,k个数都为sk/k:对与剩下的数也按照同样的方 ...
随机推荐
- VBA清除Excelpassword保护,2003/2007/2010均适用
Sub Macro1() ' ' Breaks worksheet and workbook structure passwords. Jason S ' probably originator of ...
- IOS中对图片进行重绘处理的方法总结
一.CGImageRef是什么 CGImageRef是定义在QuartzCore框架中的一个结构体指针,用C语言编写.在CGImage.h文件中,我们可以看到下面的定义: ? 1 typedef st ...
- HDUJ 2074 叠筐 模拟
叠筐 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...
- FileSystemWatcher使用方法具体解释
FileSystemWatcher控件主要功能: 监控指定文件或文件夹的文件的创建.删除.修改.重命名等活动.能够动态地定义须要监控的文件类型及文件属性修改的类型. 1.经常使用的几个基本属性: (1 ...
- js判断是否是数字通用写法
function isNumber(value){ var isNumber = value.match(/^(-?\d+)(\.\d+)?$/g) !=null; if(value.substrin ...
- jquery返回顶部
// 返回顶部 var fixed_totop = $('.back_top').on('click',function(){ $('html, body').animate({scrollTop: ...
- Android Training: 设备管理
Android 设备管理 Android2.2 通过Android设备管理API提供对企业级应用的支持.设备管理API在系统级别提供了设备管理特性.这些API可以在企业环境下,需要对员工设备进行控制时 ...
- C#中的委托和游戏中的运用
C#中的委托与游戏中的运用 1.什么是委托 在C/C++中,有函数指针的概念,即指向函数的指针.当我们调用该指针时,就相当于调用了该指针所指向的函数,这就是函数指针的一个作用,而他另一个作用就是将自己 ...
- 三维偏序-二维LIS
Another Longest Increasing Subsequence Problem 有两种思路. 思路一: 考虑到如果只有一维,那么可以用f[s]表示长度为s时,最后一个数是多少,把这个想法 ...
- OpenCV——Mat,IplImage,CvMat类型转换
Mat,cvMat和IplImage这三种类型都可以代表和显示图像,三者区别如下 Mat类型侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化. 而CvMat和IplImage类型更侧 ...