UVA 10570 Meeting with Aliens 外星人聚会
2015-08-10 00:57
375 查看
题意:给你一个排列,每次可以交换两个整数(不一定要相邻),求最少交换次数把排列变成一个1~n的环形排列。(正反都算)
其实就是找环了,对于一个链状序列,最小交换次数等于不在对应位置的数字个数减去环的个数。
至于证明这里讲的比较详细:http://www.dewen.io/q/7967#ans16319
所以只要枚举一下环的起点就好了,dfs找环就行了。
其实就是找环了,对于一个链状序列,最小交换次数等于不在对应位置的数字个数减去环的个数。
至于证明这里讲的比较详细:http://www.dewen.io/q/7967#ans16319
所以只要枚举一下环的起点就好了,dfs找环就行了。
#include<bits/stdc++.h> using namespace std; const int maxn = 1e3+233; #define bug(x) cout<<#x<<'='<<x<<endl; int a[maxn]; bool vis[maxn]; int cnt,s; void dfs(int u) { if(vis[u]) return; cnt++; vis[u] = true; dfs(a[u+s]); } int n; void dfs2(int u) { if(vis[n-1-u]) return; cnt++; vis[n-1-u] = true; dfs2(a[n-1-u+s]); } int main() { //freopen("in.txt","r",stdin); while(~scanf("%d",&n)&&n){ for(int i = 0; i < n; i++){ scanf("%d",a+i); a[i+n] = --a[i]; } int ans = INT_MAX; for( s = 0; s < n; s++){ int cur = 0; memset(vis,0,sizeof(vis)); for(int i = 0; i < n; i++)if(!vis[i]) { if(a[i+s] != i) { vis[i] = true; cnt = 0; dfs(a[i+s]); cur += cnt; }else vis[i] = true; } ans = min(ans,cur); } reverse(a,a+2*n); for( s = 0; s < n; s++){ int cur = 0; memset(vis,0,sizeof(vis)); for(int i = 0; i < n; i++)if(!vis[i]) { if(a[i+s] != i) { vis[i] = true; cnt = 0; dfs(a[i+s]); cur += cnt; }else vis[i] = true; } ans = min(ans,cur); } printf("%d\n",ans); } return 0; }
相关文章推荐
- ObjectMapper转换时包含日期会报错
- 《程序员的呐喊》读书笔记(下)
- 自适应移动设备页面的设计
- hdu1702(ACboy needs your help again!) 在杭电又遇坑了
- Git 基本的工作流程
- 移动页面自适应手机屏幕宽度HTML5开发
- Nginx 笔记与总结(10)Nginx 与 PHP 整合
- Regionals 2009 Asia - Hsinchu uvalive 4526 Inventory - dp
- Unique Paths I
- 构建施耐德楼控系统数据库后台服务器示例工程四(SQLServer查询语句)
- nyoj 488&&hdu 1016 素数环【dfs】
- Java序列化基础
- win10囧冏记
- 冒泡排序法
- 华为交换机删除不了vlan
- conn.setAutoCommit(false)数据回滚设置
- 简单排队叫号功能实现
- Mac 修改AppleID 使用“登录”钥匙串
- Stack总结
- 杭电1564 Play a game