题目来源:http://poj.org/problem?id=1033

题目大意:

  某操作系统的文件系统中,所有的磁盘空间被分为N个大小相等的cluster,编号1至N。每个文件占用一个或多个cluster。所有没有被文件占用的cluster称为是空闲的。磁盘上的一个文件如果放置在连续的cluster上,读取速度是最快的。

  磁盘以匀速旋转,磁头找到某一个cluster的时间的不等的。因此,找到靠近开头的cluster更快。所有的文件被事先按访问频率高到低编号1到K,最好的文件放置方式是:文件1放置于cluster 1,2,...S1,文件2放置于cluster S1+1, S1+2,...S1+S2.后面类似,紧挨着放置。Si表示第i个文件占据的cluster数。

  为了将磁盘上的文件整理成上述的最优放置方式,需要对cluster进行移动。一次移动包括将一个cluster的内容读出来,写至一块空闲的cluster上,完成后之前的那块cluster变为空闲。

  程序的目标是将磁盘上的文件变为最优放置方式需要的最少移动次数和移动次序。

输入:第一行含两个整数N和K分别代表cluster数和文件数。接下来K行,每行代表一个文件,第一个数字代表该文件含多少cluster,后面的每个数字代表所占的cluster的编号。

输出:按顺序输出表示移动的数据对Pj,Qj。表示将Pj号cluster的数据移动到Qj.(答案可能不唯一,采用了Special Judge,只要答案正确即可)不需要移动则输出"No optimization needed".


Sample Input

20 3
4 2 3 11 12
1 7
3 18 5 10

Sample Output

2 1
3 2
11 3
12 4
18 6
10 8
5 20
7 5
20 7

实际上可以把问题看过一个数组的重新排列问题.用clusters[N]数组表示第i块cluster处放置的文件块的序号(块的序号按重排后结果编排,即该块最终应该位于哪一个cluster)。那么重排后的结果应该是前面部分的clusters[i]=i,后面的部分clusters[i]=0.

比如sample中的例子:

初始状态:

  i:      1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18

clusters[i]:  0  1  2  0  7  0  5  0  0   8    3    4    0    0   0    0    0    6

重排后:

  i:      1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18

clusters[i]:  1  2  3  4  5  5  6  8  0   0    0    0    0    0   0    0    0    0

遍历所有的cluster,会有以下几种情况:

1. clusters[i]=0,不必处理。

2. clusters[i]=1,不必处理。

3. 不是以上两种情况,则需要移动cluster。此时又有两种情况:

  a.需要移动的cluster形成链,例如:

     i:   1  2  3  4  5  6     

   clusters[i]: 5  0  4  2  3  0

   1被5占,5被3占,3被4占,4被2占,2为空。用栈保存占用关系,借助一个空位,逆向移动即可。

  b.需要移动的cluster形成环,例如:  

      i:  1  2  3  4  5  6     

    clusters: 5  1  4  2  3  0

  1被5占,5被3占,3被4占,4被2占,2又被1占。这种情况从磁盘末尾开始找一个空cluster(题目保证了一个至少有一个空的cluster,否则就移动不了了),借助这个空的cluster,然后逆向移动。

  遍历完成时磁盘整理也完成了。

 //////////////////////////////////////////////////////////////////////////
// POJ1033 Defragment
// Memory: 408K Time: 829MS
// Language: C++ Result: Accepted
////////////////////////////////////////////////////////////////////////// #include <iostream>
#include <stack> using namespace std; int main() {
int N;
int K;
int move_cnt = ;
cin >> N >> K; int * clusters = new int[N + ];
for (int i = ; i <= N; ++i) {
clusters[i] = ;
}
int sum = ;
for (int i = ; i < K; ++i) {
int n;
cin >> n;
for (int j = ; j <= n; ++j) {
int a;
cin >> a;
clusters[a] = ++sum;
}
}
for (int i = ; i <= N; ++i) {
if (clusters[i] == || clusters[i] == i) {
continue;
}
stack<int> s;
int next = clusters[i];
s.push(i);
bool isCircle = false;
while (true) {
if (clusters[next] == i) {
isCircle = true;
break;
} else if (clusters[next] == ) {
break;
}
s.push(next);
next = clusters[next];
}
if (isCircle == true) {
int j = N;
while (clusters[j] != ) {
--j;
continue;
}
cout << next << " " << j << endl;
clusters[j] = clusters[next];
int t;
while (!s.empty()) {
t = s.top();
cout << t << " " << next << endl;
clusters[next] = clusters[t];
next = t;
s.pop();
++move_cnt;
}
clusters[next] = clusters[j];
clusters[j] = ;
cout << j << " " << next << endl;
} else {
int t;
while (!s.empty()) {
t = s.top();
cout << t << " " << next << endl;
clusters[next] = clusters[t];
next = t;
s.pop();
++move_cnt;
}
clusters[next] = ;
}
}
if (move_cnt == ) {
cout << "No optimization needed" << endl;
}
system("pause");
return ;
}

POJ1033 Defragment的更多相关文章

  1. IP defragment

    snort IP defragment 模型: BSD favors an original fragment with an offset that is less than or equal to ...

  2. POJ 1033 Defragment

    根据http://hi.baidu.com/algorithm/item/d51b15f7a8ea1c0a84d278be这个开始练习ac,刚开始接触这道题时以为是道搜索题,读完之后深思了一下,感觉不 ...

  3. poj1033

    模拟题,注意不需要移动的情况要特殊输出 #include <cstdio> #include <cstring> #include <cstdlib> using ...

  4. erlang 分布式数据库Mnesia 实现及应用

    先推荐一篇:mnesia源码分析(yufeng)   - linear hash   ETS/DETS/mnesia 都使用了linear hash算法 http://en.wikipedia.org ...

  5. angular源码分析:angular中$rootscope的实现——scope的一生

    在angular中,$scope是一个关键的服务,可以被注入到controller中,注入其他服务却只能是$rootscope.scope是一个概念,是一个类,而$rootscope和被注入到cont ...

  6. 云与备份之(1):VMware虚机备份和恢复

    本系列文章会介绍云与备份之间的关系,包括: (1)VMware 虚机备份和恢复 (2)KVM 虚机备份和恢复 (3)云与备份 (4)OpenStack 与备份 (5)公有云与备份 1. 与备份有关的V ...

  7. HANA SQL

    约束 注释 你可以给你的 SQL 语句添加注释来增加可读性和可维护性. SQL 语句中注释的分隔如下: l  双连字符“--”.所有在双连字符之后直到行尾的内容都被 SQL 解析器认为是注释. l  ...

  8. POJ题目排序的Java程序

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

  9. 如何使用vmware-vdiskmanager增加磁盘空间

    VMware Virtual Disk Manager Usage: vmware-vdiskmanager.exe OPTIONS <disk-name> | <mount-poi ...

随机推荐

  1. CSS3 日常小结

    1. pointer-events:none; 2. flex 今天看到一个牛X的CSS3属性 flex, 称为弹性盒子.  这中属性完全可以替代媒体查询啦 使用方法: 父元素使用属性display ...

  2. netty中的引导Bootstrap服务端

    引导一个应用程序是指对它进行配置,并使它运行起来的过程. 一.Bootstrap 类 引导类的层次结构包括一个抽象的父类和两个具体的引导子类,如图 8-1 所示 服务器致力于使用一个父 Channel ...

  3. JAVA 1.5 并发之 ReentrantLock

    在文章里我不打算具体讲Lock的实现,对此有兴趣的请点击这篇博文 http://www.blogjava.net/BucketLi/archive/2010/09/30/333471.html 我是一 ...

  4. oracle--pl/sql变量定义----

    一.变量介绍 在编写pl/sql程序时,可以定义变量和常量:在pl/sql程序中包括有: 1).标量类型(scalar) 2).复合类型(composite) --用于操作单条记录 3).参照类型(r ...

  5. java 设置Cookie值

    原文地址:http://blog.csdn.net/lansetiankong12/article/details/52622654 /** * 读取所有cookie * 注意二.从客户端读取Cook ...

  6. [51nod1247]可能的路径(思维题)

    题意:给定(a,b),(x,y)  ,(a,b)可以通向(a-b,b) (a+b,b) (a,a+b) (a,a-b) 求能否到达(x,y) 解题关键:类似于更相减损,变换过程中gcd是一样的. #i ...

  7. Spring示例工程

    ---------------siwuxie095                                 创建一个基于 Spring IoC 的小程序的步骤:     建立 Spring 工 ...

  8. VSCode编写C/C++项目

    VSCode编写C/C++项目 1. 下载插件C/C++.C++ Intellisense;2. 新建一个空文件夹,从VSCode打开. (或File-->Open Folder-->新建 ...

  9. php学习笔记-php中把浮点数转化为整数

    在php中有时候会遇到比如 14.6%3这种操作,php是会先把14.6转化为整数再做其它的操作,那么这个转化为整数的操作是floor(14.6)还是ceil(14.6)还是round(14.6)呢? ...

  10. 【PHP】composer 常用命令