根据http://hi.baidu.com/algorithm/item/d51b15f7a8ea1c0a84d278be这个开始练习ac,刚开始接触这道题时以为是道搜索题,读完之后深思了一下,感觉不需要套用一贯的dfs或者bfs,直接根据自己的思路走,然后注意一下效率问题就行了!可见算法注重灵活,而不是一贯的套用现有的模式。

利用题中示例:

簇号from[]:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
     目前簇中内容应该在的簇号to[]:0 1 2 0 7 0 5 0 0   8   3   4    0   0    0   0   0    6   0   0

很自然的想法就是同时遍历from和to数组,如果from和to中内容相同,说明当前簇中内容不需要移动,否则为了优化必须进行移动,但是可以移动的前提是to所指的簇中内容为空,即from[to[i]]=0。可以先把满足移动条件的进行移动,由于移动之后,可能会引起其它簇满足移动条件,所以还需要再次遍历from和to,直到没有满足移动的簇。这个时候,有两种情况,一是达到优化状态,即from=to;另外一种是存在一个环,就如题中的5-7,7-5。针对第二种情况就是打破环,然后再次对满足移动条件的簇进行移动。多个嵌套循环就能解决了,但是这个过程使得需要多次遍历才能把所有满足移动条件的簇操作完全(由于移动导致了其他一些簇满足了移动条件后,需要第二次遍历才能将这些簇进行移动)。很明显会超时的。

有没有可能使得一次遍历之后,就能把不属于环的一些簇全部移动到位呢?答案是肯定的。

看下面代码,opt[]指在优化之后,簇i存放的是原来的簇opt[i]的内容。

#include <iostream>
#include <vector>
using namespace std;
int n, k;
vector<int> opt ;
vector<int> c2f;
int count;
bool moved = false;
void MoveBeginAt(int pos)
{
while( opt[pos] != 0 && !c2f[pos] )
{
int from = opt[pos];
int to = pos;
cout << from << " " << to << endl;
moved = true;
c2f[to] = c2f[from];
c2f[from] = 0;
opt[pos] = pos;
pos = from;
}
}
int MaxFreeIndex()
{
int i = c2f.size();
while( c2f[--i] );
return i;
}
int main()
{
while( cin >> n >> k )
{
opt.assign(n+1, 0);
c2f.assign(n+1, 0);
count = 0;
moved = false;
for(int i = 0; i < k; ++i)
{
int m; cin >> m;
for(int j = 0; j < m; ++j)
{
int c;
cin >> c;
opt[++count] = c;
c2f[c] = i + 1;
}
}
for(int i = 1; i <= count; ++i)
if( !c2f[i] )
MoveBeginAt( i );
int from = 0 ;
for(int i = 1; i <= count; ++i)
{
if( opt[i] != i )
{
if( !from )
from = i;
else if( opt[i] == from )
{
int to = MaxFreeIndex();
cout << from << " " << to << endl;
opt[i] = to;
c2f[to] = c2f[from];
c2f[from] = 0;
MoveBeginAt( from );
i = from ;
from = 0;
}
}
}
cout << (moved?"":"No optimization needed\n") ;
}
return 0;
}

另外还有一种利用栈的解法,也很巧妙,思路见 http://www.cnblogs.com/damacheng/archive/2010/09/24/1833983.html;代码实现如下:

#include <iostream>
#include <stack>
#include <vector>
using namespace std;
int n, k;
vector<int> opt;
stack<int> s;
int count ;
int MaxFreeIndex()
{
int i = opt.size() - 1;
while( opt[i] )
--i;
return i;
}
void Work()
{
bool moved = false;
for(int i = 1; i < opt.size(); ++i){
if( opt[i] && opt[i] != i ){
moved = true;
s.push( i );
int b = i, cur = opt[i];
while( true ){
s.push( cur );
if( !opt[cur] )
break;
else if( opt[cur] == b ){
int j = MaxFreeIndex();
cout << cur << " " << j << endl;
opt[j] = b;
opt[cur] = 0;
break;
}
cur = opt[cur];
}
int from, to = s.top();
s.pop();
while( !s.empty() ){
from = s.top();
cout << from << " " << to << endl;
opt[to] = opt[from];
to = s.top();
s.pop();
}
opt[to] = 0;
}
}
cout << (moved?"":"No optimization needed\n") ;
}
int main()
{
while( cin >> n >> k ){
opt.assign( n + 1, 0 );
count = 0;
for(int i = 0; i < k; ++i){
int m;
cin >> m;
for(int j = 0; j < m; ++j){
int c;
cin >> c;
opt[c] = ++count;
}
}
Work();
}
return 0;
}

POJ 1033 Defragment的更多相关文章

  1. POJ题目排序的Java程序

    POJ 排序的思想就是根据选取范围的题目的totalSubmittedNumber和totalAcceptedNumber计算一个avgAcceptRate. 每一道题都有一个value,value ...

  2. 【动态规划】POJ 1161 & ZOJ1463 & XMU 1033 Brackets sequence

    题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1033 http://poj.org/problem?id=1141 ZOJ目前挂了. ...

  3. POJ1033 Defragment

    题目来源:http://poj.org/problem?id=1033 题目大意: 某操作系统的文件系统中,所有的磁盘空间被分为N个大小相等的cluster,编号1至N.每个文件占用一个或多个clus ...

  4. [ACM训练] 算法初级 之 搜索算法 之 广度优先算法BFS (POJ 3278+1426+3126+3087+3414)

    BFS算法与树的层次遍历很像,具有明显的层次性,一般都是使用队列来实现的!!! 常用步骤: 1.设置访问标记int visited[N],要覆盖所有的可能访问数据个数,这里设置成int而不是bool, ...

  5. POJ推荐50题

    此文来自北京邮电大学ACM-ICPC集训队 此50题在本博客均有代码,可以在左侧的搜索框中搜索题号查看代码. 以下是原文: POJ推荐50题1.标记“难”和“稍难”的题目可以看看,思考一下,不做要求, ...

  6. 双向广搜 POJ 3126 Prime Path

      POJ 3126  Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16204   Accepted ...

  7. POJ 3126 Prime Path (BFS)

    [题目链接]click here~~ [题目大意]给你n,m各自是素数,求由n到m变化的步骤数,规定每一步仅仅能改变个十百千一位的数,且变化得到的每个数也为素数 [解题思路]和poj 3278类似.b ...

  8. POJ题目细究

    acm之pku题目分类 对ACM有兴趣的同学们可以看看 DP:  1011   NTA                 简单题  1013   Great Equipment     简单题  102 ...

  9. poj 3126 Prime Path bfs

    题目链接:http://poj.org/problem?id=3126 Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

随机推荐

  1. Python 2.7 Exception格式化工具

    首先说一个发现: try: 抛错误,抛异常 except Exception as e: 都被这里抓住了 except Error as e: 这里啥事都没了 然后,说说Exception as e的 ...

  2. QT最简单的程序执行过程分析(内含C++基础知识)

    打开QT Creator,新建一个“应用程序-Qt Widgets Application”项目: 输入名称scdc之后点击下一步. 在“构建套件”这个页面中直接点出下一步,然后再输入自己的类名Dat ...

  3. Zend server最大化应用程序的性能、扩展性和可用性

    如果我有8个小时去砍到一棵树,我会花6个小时磨斧子”——林肯(美国总统) 你可以知道? 世界页面访问量的峰值超过7000万每分钟. CloudFare公司服务器问题,导致785000站点崩溃一小时. ...

  4. SQL SERVER – Import CSV File Into SQL Server Using Bulk Insert – Load Comma Delimited File Into SQL Server

    CSV stands for Comma Separated Values, sometimes also called Comma Delimited Values. Create TestTabl ...

  5. Ruby on Rails (ROR)类书籍

    Ruby on Rails (ROR)类书籍下载地址及其他(整理) Ruby on Rails 如此之热,忍不住也去看了看热闹,现在把一些相关的电子图书下载地址整理下,方便有兴趣的朋友. 2006-0 ...

  6. solr的安装与配置

    solr的安装与配置 不久之前开发了一个项目,需要用到solr,因为所以在开始再网上查找资料,但是发现大部分的资料都是很片面的,要么就是只讲解solr如何安装的,要么就是只讲解solr的某一个部分的, ...

  7. Android项目---ActivityGroup的使用

    ActivityGroup在一年前已经被说明不用了,但是腾讯QQ,新浪微博上也不乏ActivityGroup的身影.所以,即使是过时的东西,也有学习的必要,当然项目中也是可以添加的.在网上找了一个博客 ...

  8. gulp package.json

    { "name": "gulpAngular1", "version": "0.0.0", "dependen ...

  9. Visual Studio 2013 Use HTTPS (SSL) On Web Application Projects

    公司调试HTTPS接口会用到,原文:http://www.codeproject.com/Tips/766918/Visual-Studio-Use-HTTPS-SSL-On-Web-Applicat ...

  10. 利用MARQUEE实现正在处理效果

    ASP.NET服务器端事件利用MARQUEE实现正在处理效果   前言:ASP.NET同仁们应该都遇到过当触发一个比较耗时的服务器端事件时,页面会处在一个等待的状态(即假死状态),用户体验非常不好,很 ...