题目来源: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. php实现多文件上传和下载。

    http://1229363.blog.163.com/blog/static/19743427200751291055264/

  2. C语言逗号运算符和逗号表达式

    在C语言中逗号","也是一种运算符,称为逗号运算符. 其功能是把两个表达式连接起来组成一个表达式, 称为逗号表达式.其一般形式为:表达式1,表达式2 其求值过程是分别求两个表达式的 ...

  3. FFmpeg 基本用法--此文转载,作为笔记

    v  容器(Container) v  容器就是一种文件(封装)格式,比如flv.mkv.ts.mp4.rmvb.avi等.包含下面5种流以及文件头信息. v  流(Stream) v  是一种视频数 ...

  4. Agc011_F Train Service Planning

    先放题面,再放LHX巨佬题解 接着就是%%%.$orz.Oro.Or2.Otz.OTL.sto.rzo.Jto$.On_.○| ̄|_啊 模拟赛里直接把这道题刚掉了 一题升天·爆踩全场 这题思维跨越度已 ...

  5. 【JVM】java方法区

    java方法区[名词解析]        --->和java堆一样,方法区是一块所有线程共享的内存区域.        --->保存系统的类信息,比如,类的字段,方法,常量池等.      ...

  6. INT 21H 指令说明及使用方法

    很多初学汇编语言的同学可能会对INT 21H这条指令感到困惑,不知道是什么意思,下面就以一段简单的程序为大家讲解: 例如:需要键盘输入,并且回显. AH的值需要查表取得,表在下面 指令:      M ...

  7. oracle单实例12.2.0.1安装

    说明:本文描述oracle linux 6.8 安装 oracle 12.2.0.1 0. 查看操作系统版本 [root@12c01 ~]# cat /etc/os-release NAME=&quo ...

  8. TVYJ1266:费解的开关

    我对状态空间的理解:https://www.cnblogs.com/AKMer/p/9622590.html 题目传送门:http://www.joyoi.cn/problem/tyvj-1266 这 ...

  9. 为什么对象序列化要定义serialVersionUID

    对于实现了java.io.Serializable接口的实体类来说,往往都会手动声明serialVersionUID,因为只要你实现了序列化,java自己就会默认给实体类加上一个serialVersi ...

  10. Navicat生成数据库结构同步SQL

    作为一个苦逼的技术男,在做开发的时候经常会遇见程序版本升级,数据库结构变化.我们需要一个快捷的方式让客户尽快从旧版本数据库结构更新至新版本数据库结构.如果每做一次改动我们就记录一下当然是好事,但是万一 ...