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这样, ...
随机推荐
- Eclipse 学习总结
一. Eclipse 中一个普通 JavaWeb 项目的目录结构 如果项目工程中没有web.xml文件,可以手动动态添加. 右击项目 -> java EE Tools -> ...
- 分布式事务slides
最近看了<分布式系统概念与设计 第 5 版>的分布式事务章节,整理了一份 ppt.还有恢复部分没有收录进来,有空再整理啦. 下面是传到 deckspeaker 上的 slides 展示: ...
- mongdb aggregate 聚合数据
最近用到的一些mongodb的数据查询方法 及api用法 Aggregate() 数据聚合处理的方法 可以将聚合的一些方法放在其后面的括号中,也可继续以agg.的样式链式加入 aggregate.al ...
- TCP协议是如何保证可靠传输的【经典】
参考:http://blog.csdn.net/cmm0401/article/details/77878998 从特点上我们已经知道,TCP 是可靠的但传输速度慢 ,UDP 是不可靠的但传输速度快. ...
- Visual C# 2010 实现菜单项和状态栏
演练:向窗体提供标准菜单项 Visual Studio 2010 其他版本 此主题尚未评级 - 评价此主题 可以通过 MenuStrip 控件为窗体提供标准菜单. 此演练演示如何使 ...
- 使用WinPcap获取网卡MAC地址
关键字:WinPcap 网卡 MAC地址 作者:txw1958 在WpdPack_4_1_2\WpdPack\Examples-remote\PacketDriver\GetMacAddress\目录 ...
- kbmmw 中XML 操作入门(跨平台,而且可以与JSON,YAML,BSON 直接互相转换)
delphi 很早以前就自带了xml 的操作,最新版里面有三种XML 解释器,一种是MSXML,看名字就知道 这个是微软自带的,这个据delphi 官方称是速度是最快的,但是只能在windows 上使 ...
- 【转载】MySQL双主双从高可用集群架构
双浮动VIP 原文地址:http://www.linuxcache.com/archives/2907 转载请注明原文地址.
- CefSharp For WPF响应页面点击事件
初始化 <!--浏览器--> <cefSharpWPF:ChromiumWebBrowser Name="webBrowser" Grid.Row="0 ...
- WPF 多点触摸开发[2]:WPF触摸的几个手势的执行顺序
原文:WPF 多点触摸开发[2]:WPF触摸的几个手势的执行顺序 前面我讲了在win7下使用模拟器,进行调试模拟多点触摸,其实际开发中这样也比较麻烦.. 要拿几个鼠标. 所以更多的人会 买个触摸套 套 ...