根据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. Light OJ 1316 A Wedding Party 最短路+状态压缩DP

    题目来源:Light OJ 1316 1316 - A Wedding Party 题意:和HDU 4284 差点儿相同 有一些商店 从起点到终点在走过尽量多商店的情况下求最短路 思路:首先预处理每两 ...

  2. SQL点滴32—Excel中CONCATENATE函数生成SQL语句

    原文:SQL点滴32-Excel中CONCATENATE函数生成SQL语句 当拿到一个Excel的时候需要将这里面的数据插入到数据库里面,该怎么办,除了使用SSIS数据导入之外还可以使用Excel中的 ...

  3. win7下的PHP+IIS配置,找不到php5isapi.dll的问题,版本5.4.9

    原文:win7下的PHP+IIS配置,找不到php5isapi.dll的问题,版本5.4.9 问题:PHP新手配置,在官网上下载的压缩包.按网上的找的教程配置IIS时发现,在解压包里找不到php5is ...

  4. Reporting Service部署之访问权限

    原文:Reporting Service部署之访问权限 SQL Server Reporting Services 并非专门设计用于 Internet 报表部署方案,但是您可以成功地将 Reporti ...

  5. 读书笔记—CLR via C#线程27章节

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

  6. Android 5.0自定义动画

    材料设计中的动画对用户的操作给予了反馈,并且在与应用交互时提供了持续的可见性.材料主题提供了一些按钮动画和活动过渡,Android 5.0允许你自定义动画并且可以创建新的动画: Touch Feedb ...

  7. ASP.NET MVC+Knockout+Web API+SignalR

    架构设计(ASP.NET MVC+Knockout+Web API+SignalR) 架构设计(ASP.NET MVC+Knockout+Web API+SignalR) 2014-01-16 18: ...

  8. Love myself...

    Sometimes we feel as if our lives rely on that one person. We think 'If I do this, he/she will like ...

  9. Content Negotiation(内容协商)

    Asp.Net Web API 2第十四课——Content Negotiation(内容协商)   前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http:// ...

  10. ASP.NET Web API中的JSON和XML序列化

    ASP.NET Web API中的JSON和XML序列化 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok ...