- 浏览: 204361 次
- 性别:
- 来自: 武汉
-
文章分类
- 全部博客 (137)
- c++ (74)
- c++,算法,回溯 (2)
- DP问题。 (9)
- DP问题,0/1背包问题 (3)
- 数学问题 (6)
- 贪心算法 (10)
- 排序 (16)
- 数据结构 (7)
- 容器 (2)
- 模拟问题 (2)
- 水题 (8)
- 并查集 (3)
- 非技术 (2)
- 素数问题 (1)
- DFS (3)
- 二叉树 (1)
- 递归 (1)
- 图论 (5)
- 最小生成树 (5)
- 最短路径 (6)
- bell_flaod算法 (2)
- hash (3)
- 二分查找 (1)
- 搜索 (5)
- BFS (5)
- STL (3)
- 字符串hash (1)
- 拓扑排序 (1)
- 字典树 (4)
- 哈弗曼树 (1)
- KMP (7)
- 线段树 (9)
- 树状数组 (6)
- 全排列 (2)
- DP问题 (2)
- LCS (1)
- 最长不下降子序列 (2)
- 面试经验 (3)
题目大意:你要写一个OS,要实现磁盘碎片整理的功能。磁盘分为N个簇,一个文件可以占用K个簇,(1 <= K < N <= 10000),给出各个文件的占用磁盘的情况,也就是一个文件占用了哪些簇,想要进行碎片整理,就是把这些簇按顺序整理到磁盘的最顶部,例如给出示例:文件1:2 3 11 12,占用了4个簇,编号为1-4。 文件3:18 5 10,占用了3个簇,编号为6-8。 初始状态是这样的,0表示未占用: 簇号: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 逻辑编号:0 1 2 0 7 0 5 0 0 8 3 4 0 0 0 0 0 6 一共整理到最后,磁盘的情况最后是这样的: 簇号: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 逻辑编号:1 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0 0 0 写一个程序得到整理好碎片最少需要多少步操作,并把这些操作打印出来。比如说第1个簇的内容放到第2个簇,打印出1 2。操作的定义是这样的:把一个簇的内容放到另个一个簇中,算是一步操作。 注意这里是Special Judge,意思是只要答案符合要求就行了,不必和SAMPLE中的OUTPUT一样也可以AC。 怎么才能找到最少的步数呢?我想了半天也没怎么想出来,于是看了看DISCUSS,总结以下: 遍历整个磁盘,设i为当前遍历的簇的编号,clusters为整个磁盘,clusters[i]表示第i个簇是否被占用,被哪个编号的文件片段占据。 (1) 如果clusters[i]为0,也就是未被使用,不进行处理。 (2) 如果clusters[i]为i,也就是已经到了整理好的状态,不进行处理。 (3) 如果clusters[i]不满足1和2,则又有两种情况。 情况一:磁盘使用情况成链:如图所示: 簇号: 1 2 3 4 5 6 ... 逻辑编号:5 0 4 2 3 0 ... 第1个簇被第5个文件片断占据,第5个簇又被第3个文件片段占据,第3个簇又被第4个文件片段占据,第4个簇又 被第2个文件片断占据,第2个簇未被占据。算法就很简单了,按照簇被访问的反方向: clusters[2] = clusters[4],clusters[4] = clusters[3],clusters[3] = clusters[5], clusters[5] = clusters[1],最后clusters[1] = 0。怎么样反方向呢,使用一个栈就好了。 情况二:磁盘使用情况成环:如图所示: 簇号: 1 2 3 4 5 6 ... 逻辑编号:5 1 4 2 3 0 ... 这种情况跟情况一差不多,只是最后clusters[2]指向了第1个簇,这样就形成了一个环,这里只是需要额外的 处理一下,就像交换2个变量一样,先在从磁盘末尾找到1个空的簇,因为题目保证至少有一个空的簇,先把 clusters[2]放到这个空的簇中,然后再执行情况1中的操作,最后再把空的簇的值赋给clusters[1]就好了。 最后注意一点,如果操作次数为0,则需要输出一行信息。 代码如下:
文件2:7,占用了1个簇,编号为5。
#include <cstdio>
#include <stack>
using namespace std;
int clusters[10001]; //簇的使用情况
int cluster_num, file_num; //簇的总数和文件个数
int counter = 1; //文件片段起始编号
int mov_num = 0; //操作总数
stack<int> s;
//过程详见博客讲解
void work()
{
int next;
for(int i = 1; i <= cluster_num; ++i)
{
if(clusters[i] == i)
{
continue;
}
else if(clusters[i] != 0)
{
s.push(i);
next = clusters[i];
bool is_circle = false;
while(true)
{
if(clusters[next] == i)
{
is_circle = true;
break;
}
else if(clusters[next] == 0)
{
is_circle = false;
break;
}
s.push(next);
next = clusters[next];
}
int t, j;
if(is_circle == true)
{
for(j = cluster_num; j >= 0; --j)
{
if(clusters[j] == 0)
{
break;
}
}
printf("%d %d\n", next, j);
clusters[j] = clusters[next];
while(!s.empty())
{
t = s.top();
printf("%d %d\n", t, next);
clusters[next] = clusters[t];
next = t;
s.pop();
mov_num++;
}
clusters[next] = clusters[j];
clusters[j] = 0;
printf("%d %d\n", j, next);
} else
{
while(!s.empty())
{
t = s.top();
printf("%d %d\n", t, next);
clusters[next] = clusters[t];
next = t;
s.pop();
mov_num++;
}
clusters[next] = 0;
}
}
//别忘了
if(mov_num == 0)
{
printf("No optimization needed\n");
}
}
}
int main()
{
//freopen("e:/data.txt", "r", stdin);
scanf("%d %d", &cluster_num, &file_num);
for(int i = 0; i < file_num; ++i)
{
int n, t;
scanf("%d", &n);
for(int j = 0; j < n; ++j)
{
scanf("%d", &t);
clusters[t] = counter++;
}
}
work();
return 0;
}
发表评论
-
虚函数、纯虚函数、虚基类、抽象类、虚函数继承、虚继承
2013-08-29 14:34 857虚函数:虚函数是C++中用于实现多态(polymorphis ... -
排序算法总结
2013-05-17 11:00 856选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法, ... -
poj 3122
2012-12-11 19:51 887题意:作者要开一个生日party,他现在拥有n块高度都为1 ... -
poj 3273
2012-12-11 16:49 1000题意:给你天数n,和每天需要花的钱,让你把这些天分成m份(每份 ... -
字典树学习材料
2012-05-30 14:29 983字典树,又称单词查找树,Trie树,是一种树形结构,典型应 ... -
poj 1159
2012-05-28 19:08 1465题目大意:给你一段字符串,让你求出在中间最少加入几个字符 ... -
poj 3176
2012-05-28 14:47 1044大致题意: 输入一个n层的三角形,第i层有i个数,求从第 ... -
poj 1260
2012-05-28 09:54 1630题意解释: 有n个等级的珠宝,等级依次升高,等级越高价钱越高 ... -
poj 1836
2012-05-28 09:22 2732是POJ2533的扩展题。题意不难,令到原队列 ... -
poj 2533
2012-05-26 15:36 1290在做这道题目之前,首先让我们了解一下什么是LIS算法,LIS俗 ... -
poj 3267
2012-05-26 09:43 818从程序可以看出,第i个位置到L所删除的字符数,总是先取最坏情况 ... -
poj 1276
2012-05-25 16:20 2422题意: 这道题的意思是给你一堆钱,各种面值的都有,比 ... -
poj 1094
2012-05-25 13:54 1126题意:给出字母个数,和有限个有序对(a<b)求出能确定字 ... -
poj 3393
2012-05-23 17:00 1272大致题意: 科普文一篇,文章80%都是无用信息,因为 ... -
poj 3007
2012-05-14 10:21 1004大致题意: 给定一个字符串,从任意位置把它切为两半, ... -
poj 3096
2012-05-10 21:09 1034题意: 定义D-pairs表示取字符串s中相距为D的两个字母 ... -
poj 1426
2012-04-26 20:11 2181大致题意: 给出一个整数n,(1 <= n <= ... -
poj 1797
2012-04-24 15:05 1637题目大意是就是何处一个图,n个顶点和m条边,每个边都有最大承载 ... -
poj 1338
2012-04-23 10:20 1272题意:题目意思是求由2,3,5的乘积组成的数从大到小排列,从1 ... -
poj 2021
2012-04-19 15:00 966题意:Ted今年100岁,给出n对他家族的关系:“父 ...
相关推荐
**POJ1033 Defragment** - **问题描述**:文件碎片整理问题。给定一组文件片段的原始位置和当前位置,要求重新组织文件片段使得它们按照原始顺序排列。 - **解决方案**: - 使用两个数组 `q` 和 `d` 来记录文件...
- **1011** 和 **1033** 两题适合初步了解搜索算法的应用场景。 - **1129** 和 **2049** 可以帮助进一步加深对搜索的理解。 - **2056** 和 **2488** 这两个题目则提供了不同的挑战,特别是 **2492** 还提供了一个...
推荐题目如1011、1033、1129、2049、2056、2488、2492等,其中2492可以考虑使用并查集解决。 3. **贪心**(Greedy) 贪心算法在每一步选择局部最优解,期望达到全局最优。推荐题目有1065、2054、1521、2709等,...
2. **搜索算法**:包括深度优先搜索(DFS)和广度优先搜索(BFS),如1011、1033、1129、2049和2056等,其中2488和2492难度较高,可以挑战。 3. **贪心算法**:贪心策略是在每一步选择中都采取当前状态下最好或最优...
buaa 1033 Easy Problem:在一条线段上找到一点,与给定的 P 点距离最小。这个问题可以用三分法来解决。Calc 函数即为求某点到 P 点的距离。 ZOJ 3203 Light Bulb:人左右走动,求影子 L 的最长长度。这个问题也...
##### 3.1 buaa1033 Easy Problem **题意概述**:题目要求在线段上找到一个点,使得该点到给定点\( P \)的距离最小。这是一个典型的凸函数问题,因为点到点之间的距离函数是关于位置的凸函数。 **算法实现**: - ...