题目来源: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. 2017-2018-1 20179215《Linux内核原理与分析》第四周作业

    本次的实验是使用gdb跟踪调试内核从start_kernel到init进程启动,并分析启动的过程. 1.首先是在实验楼虚拟机上进行调试跟踪的过程. cd LinuxKernel qemu -kerne ...

  2. LuoguP4383 [八省联考2018]林克卡特树lct

    LuoguP4383 [八省联考2018]林克卡特树lct https://www.luogu.org/problemnew/show/P4383 分析: 题意等价于选择\(K\)条点不相交的链,使得 ...

  3. redis多机集群部署文档

    redis多机集群部署文档(centos6.2) (要让集群正常工作至少需要3个主节点,在这里我们要创建6个redis节点,其中三个为主节点,三个为从节点,对应的redis节点的ip和端口对应关系如下 ...

  4. Python:extend和append的用法

    转于:https://www.cnblogs.com/subic/p/6553187.html 博主:subic 1)list.append(object) 向列表中添加一个对象object2)lis ...

  5. C语言 mmap()函数(建立内存映射) 与 munmap()函数(解除内存映射)

    mmap将一个文件或者其它对象映射进内存.文件被映射到多个页上,如果文件的大小不是所有页的大小之和, 最后一个页不被使用的空间将会清零.mmap在用户空间映射调用系统中作用很大. 条件 mmap()必 ...

  6. SpringMVC 利用@ResponseBody注解返回Json时,出现406 not acceptable 错误的解决方法。

    1 在RequestMapping中加入produces属性如: @RequestMap(value="/path",produces="application/json ...

  7. WPF 导出Excel(合并单元格)

    WPF 导出Excel(合并单元格) DataTable 导出Excel(导出想要的列,不想要的去掉) ,B1,B2,B3,B4,B5} MisroSoft.Office.Interop.Excel. ...

  8. python 基础 序列化

    转自https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/00138683221577 ...

  9. 代码,用c++实现线性链表

    #include <iostream> #include <stdio.h> #include <malloc.h> using namespace std; #d ...

  10. 洛谷-铺地毯-NOIP2011提高组复赛

    题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...