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:对与剩下的数也按照同样的方 ...
随机推荐
- 格而知之15:我所理解的Block(1)
1.Block 本质上是一个struct结构体,在这个结构体中,最重要的成员是一个函数(当然除函数外还有其他重要的成员). 2.在开始解析Block之前,首先来回顾一下Block的格式.Block相关 ...
- Bin & Jing in wonderland(概率,组合数学)
Problem 2103 Bin & Jing in wonderland Accept: 201 Submit: 1048 Time Limit: 1000 mSec Memor ...
- Spring 3.x企业应用开发实战(11)----基于@AspectJ配置切面
1.@AspectJ的JDK必须是JDK 5.0+ 基于@AspectJ配置切面 @AspectJ采用注解描述切点.增强,两者只是表达式方式不同,效果相同. @AspectJ语法基础-----切点表达 ...
- hibernate 用hql做中文排序
用Hibernate+MySQL的童鞋是不是非常苦恼为什么MySQL不支持中文排序呢?没办法.仅仅有等utf8_unicode_cn 出来了.假设用hibernate即想实现跨库,又想不改代码怎样实现 ...
- STL中map,set的基本用法示例
本文主要是使用了STL中德map和set两个容器,使用了它们本身的一些功能函数(包括迭代器),介绍了它们的基本使用方式,是一个使用熟悉的过程. map的基本使用: #include "std ...
- Hacker(15)----嗅探原理
嗅探指窃听网络中流经的数据包,这里的网络一般指用集线器或路由器组建的局域网.通过嗅探并解析数据包,便可知道数据包中的信息,一旦含有账户密码等隐私信息就可能造成个人资金损失. 嗅探数据包无法通过输入命令 ...
- EffectiveC#2--为你的常量选择readonly而不是const
1.对于常量,C#里有两个不同的版本: 编译时常量--效率相比更高些,但可维护性不好,保留的目的是为了性能.const关键字申明 public const int _Millennium = 2000 ...
- uva 1596 Bug Hunt
In this problem, we consider a simple programming language that has only declarations of one-dimensi ...
- hdu 1042 N!(高精度乘法)
Problem Description Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N! Input One N in ...
- HIBERNATE - 符合Java习惯的关系数据库持久化(精华篇)
HIBERNATE - 符合Java习惯的关系数据库持久化 下一页 HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.0.4 目录 前言 1. ...