SPOJ1421_Goods_循环节
题意:1~n的一个排列,两两互换,每个位置每天只能做一次交换,问最多几天能交换成1~n,并且输出交换步骤。
解法:把该置换中所有的循环节找出,各循环节之间的交换是并行的,两两不相关,每天只需在循环节内部交换。
若循环节长度为1,则无需交换,若循环节长度为2,则只需交换一次,若循环长度>2,则只需要交换2次。
置换方法:每个循环节中的第一个和最后一个交换,第二个和倒数第二个交换...
至于为什么只需两次,可以在纸上模拟一下置换过程,按上述置换方法一次交换后,一个循环节变成了(n-1)/2个长度为2的循环节,可以一次并行交换。
代码如下:
/*************************************************************************
> File Name: D.cpp
> Author: Chierush
> Mail: qinxiaojie1@gmail.com
> Created Time: 2013年07月24日 星期三 09时04分46秒
************************************************************************/ #include <iostream>
#include <cstring>
#include <cstdlib>
#include <set>
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <algorithm> #define LL long long
#define LLU unsigned long long using namespace std; bool vis[5005];
int c[5005],n,a[5005],b[5005],_count;
vector<int>s[5005]; inline void swap(int &x,int &y)
{
x=x^y,y=x^y,x=x^y;
} void dfs(int x)
{
int y=a[x],Count=1;
while (y!=x)
{
++Count;
y=a[y];
}
c[x]=Count;
y=a[x];
while (y!=x)
{
vis[y]=true;
c[y]=Count;
y=a[y];
}
s[_count].clear();
if (Count>1)
{
s[_count].push_back(x);
y=a[x];
while (y!=x)
{
s[_count].push_back(y);
y=a[y];
}
++_count;
}
} int main()
{
scanf("%d",&n);
_count=0;
for (int i=1;i<=n;++i)
scanf("%d",&b[i]);
for (int i=1;i<=n;++i)
a[b[i]]=i;
for (int i=1;i<=n;++i)
if (!vis[i])
{
vis[i]=true;
dfs(i);
}
int ans=0;
for (int i=1;i<=n;++i)
if (c[i]>ans)
ans=c[i];
if (ans==1) ans=0;
else if (ans==2) ans=1;
else ans=2;
printf("%d\n",ans);
while (ans)
{
int z=0;
for (int i=0;i<_count;++i)
z+=s[i].size()/2;
printf("%d",z);
for (int i=0;i<_count;++i)
{
for (int j=0;j<s[i].size()/2;++j)
{
printf(" %d-%d",s[i][j],s[i][s[i].size()-j-1]);
swap(a[s[i][j]],a[s[i][s[i].size()-j-1]]);
}
}
printf("\n");
_count=0;
memset(vis,0,sizeof(vis[0])*(n+1));
memset(c,0,sizeof(c[0])*(n+1));
for (int i=1;i<=n;++i)
if (!vis[i])
{
vis[i]=true;
dfs(i);
}
ans=0;
for (int i=1;i<=n;++i)
if (c[i]>ans)
ans=c[i];
if (ans==1) ans=0;
else if (ans==2) ans=1;
else ans=2;
/*for (int i=1;i<=n;++i)
printf("%d ",a[i]);
printf("\n");*/
}
return 0;
}
SPOJ1421_Goods_循环节的更多相关文章
- UVA 10692 Huge Mods(指数循环节)
指数循环节,由于a ^x = a ^(x % m + phi(m)) (mod m)仅在x >= phi(m)时成立,故应注意要判断 //by:Gavin http://www.cnblogs. ...
- 【POJ 2406】Power Strings(KMP循环节)
终于靠着理解写出KMP了,两种KMP要代码中这种才能求循环节.i-next[i]就是循环节. #include<cstdio> #define N 1000005 char s[N]; i ...
- HNU 12869 Sequence(循环节)
题目链接:http://acm.hnu.cn/online/?action=problem&type=show&id=12869 解题报告:看到n的范围这么大,一看就是找规律,把前30 ...
- Codeforces Round #383 (Div. 2) A,B,C,D 循环节,标记,暴力,并查集+分组背包
A. Arpa’s hard exam and Mehrdad’s naive cheat time limit per test 1 second memory limit per test 256 ...
- 51Node 1035----最长的循环节
51Node 1035----最长的循环节 正整数k的倒数1/k,写为10进制的小数如果为无限循环小数,则存在一个循环节,求<=n的数中,倒数循环节长度最长的那个数. 1/6= 0.1 ...
- POJ 2185 Milking Grid KMP(矩阵循环节)
Milking Grid Time Limit: 3000MS Memory Lim ...
- KMP模板,最小循环节
(可以转载,但请注明出处!) 下面是有关学习KMP的参考网站 http://blog.csdn.net/yaochunnian/article/details/7059486 http://blog. ...
- HDU 3746 Cyclic Nacklace 环形项链(KMP,循环节)
题意: 给一个字符串,问:要补多少个字符才能让其出现循环?出现循环是指循环节与字符串长度不相等.比如abc要补多个变成abcabc.若已经循环,输出0. 思路: 根据最小循环节的公式,当len%(le ...
- UVA 10298 Power Strings 字符串的幂(KMP,最小循环节)
题意: 定义a为一个字符串,a*a表示两个字符相连,即 an+1=a*an ,也就是出现循环了.给定一个字符串,若将其表示成an,问n最大为多少? 思路: 如果完全不循环,顶多就是类似于abc1这样, ...
随机推荐
- Android菜鸟的成长笔记(22)——Android进程间传递复杂数据(AIDL)
在上一篇中介绍了Andorid中的进程间的通信方式AIDL,本篇文章将介绍传递复杂数据的AIDL Service 下面通过一个示例说明: 本例子中用到了两个自定义类型:Person与Pet, 其中Pe ...
- 收集 天创恒达高清采集卡TC-5A0N7
版权声明:本文博客琅邪工作室原创文章,博客,未经同意不得转载.
- Java易混点记录
1.Java 默认将所有成员变量和成员方法与 this 关联在一起,因此使用 this 在某些情况下是多余的. 2.只要类存在,程序就可以访问该类的类变量,语法如下: 类.类变量. 只要实例存在,程序 ...
- Dojo第一节:学会使用firebug对js,Dojo进行调适
内容概要: 学会使用firebug的基本功能 1. 简介:Firebug是Firefox的一个插件,用来对js代码进行调适的工具. (官方废话:Firebug是firefox下的一个插件,可以调试全部 ...
- struts2和velocity整合问题
以下是我第一次使用velocity的时候写的 2012-03-12 话说struts真够懒的,都把velocity-1.6.4.jar放到他自己的lib里边了,就不给放全了,搞得新手太郁闷了.stru ...
- 使用UISegementControl实现简易Tomcat程序
// // TomViewController.m #import "TomViewController.h" #import <AVFoundation/AVFoundat ...
- php自动加载类文件探讨,spl_autoload_register自动加载原理
spl_autoload_register函数是实现自动加载未定义类功能的的重要方法,所谓的自动加载意思就是 我们的new 一个类的时候必须先include或者require的类文件,如果没有incl ...
- docker入门2:基础操作(1)
-- 列出所有的容器 docker ps -a (没有-a就是只列出启动的) -- 开启/关闭/移除容器 docker start|stop|rm CONTAINER_ID|CONTAINER_NA ...
- 浅谈java枚举类
一.什么情况下使用枚举类? 有的时候一个类的对象是有限且固定的,这种情况下我们使用枚举类就比较方便? 二.为什么不用静态常量来替代枚举类呢? public static final int SEASO ...
- markdownpad 2 的使用
1. 注册 邮箱:Soar360@live.com 授权秘钥: GBPduHjWfJU1mZqcPM3BikjYKF6xKhlKIys3i1MU2eJHqWGImDHzWdD6xhMNLGVpbP2M ...