POJ 1033

Defragment

Time Limit: 2000MS Memory Limit: 10000K
Total Submissions: 4990 Accepted: 1752
Case Time Limit: 1000MS Special Judge

Description

You are taking part in the development of a "New Generation" operating system and the NG file system. In this file system all disk space is divided into N clusters of the equal sizes, numbered by integers from 1 to N. Each file occupies one or more clusters in arbitrary areas of the disk. All clusters that are not occupied by files are considered to be free. A file can be read from the disk in the fastest way, if all its clusters are situated in the successive disk clusters in the natural order. 
Rotation of the disk with constant speed implies that various amounts of time are needed for accessing its clusters. Therefore, reading of clusters located near the beginning of the disk performs faster than reading of the ones located near its ending. Thus, all files are numbered beforehand by integers from 1 to K in the order of descending frequency of access. Under the optimal placing of the files on the disk the file number 1 will occupy clusters 1, 2, ..., S1, the file number 2 will occupy clusters S1+1, S1+2, ..., S1+S2 and so on (here Si is the number of clusters which the i-th file occupies). 
In order to place the files on the disk in the optimal way cluster-moving operations are executed. One cluster-moving operation includes reading of one occupied cluster from the disk to the memory and writing its contents to some free cluster. After that the first of them is declared free, and the second one is declared occupied. 
Your goal is to place the files on the disk in the optimal way by executing the minimal possible number of cluster-moving operations. 

Input

The first line of the input file contains two integers N and K separated by a space(1 <= K < N <= 10000).Then K lines follow, each of them describes one file. The description of the i-th file starts with the integer Si that represents the number of clusters in the i-th file (1 <= Si < N). Then Si integers follow separated by spaces, which indicate the cluster numbers of this file on the disk in the natural order. 
All cluster numbers in the input file are different and there is always at least one free cluster on the disk. 

Output

Your program should write to the output file any sequence of cluster-moving operations that are needed in order to place the files on the disk in the optimal way. Two integers Pj and Qj separated by a single space should represent each cluster-moving operation. Pj gives the cluster number that the data should be moved FROM and Qj gives the cluster number that this data should be moved TO. 
The number of cluster-moving operations executed should be as small as possible. If the files on the disk are already placed in the optimal way the output should contain only the string "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

 

你要写一个OS,要实现磁盘碎片整理的功能。磁盘分为N个簇,一个文件可以占用K个簇,(1 <= K < N <= 10000),给出各个文件的占用磁盘的情况,也就是一个文件占用了哪些簇,想要进行碎片整理,就是把这些簇按顺序整理到磁盘的最顶部,例如给出示例:

 

  文件1:2 3 11 12,占用了4个簇,编号为1-4。
  文件2:7,占用了1个簇,编号为5。

  文件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)查找到一个环,即此簇保存的文件是查找的起点,此时需要使用一个空闲的簇,增加移动的空间。

设space保存簇中存储的文件编号,cluster保存文件对应的簇。

对应情况1:

假设1  2

       0  1,移动顺序应为2->1,移动后状态为

       1  2

       1  0,即space[1]=1, cluster[1]=1, space[2] = 0;

情况2.1:

假设  1  2  3

         0  1  2,移动顺序为2->1, 3->2,移动后

         1  2  3

         1  2  0,

情况2.2:

假设   1  2  3  4

          3  1  2  0,通过使用空闲的4号簇打破环完成移动。

注意递归中完成当前移动后对状态进行修改。

程序:

#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;

int space[10010], cluster[10010];
int n, freespace=0, flag=-1;

void swap(int a, int b, int c, int d) {
    space[a] = b;
    space[c] = d;
    printf("%d %d\n", c, a);
}

void dfs(int now) {
    if (space[now] == 0) {
        swap(now, now, cluster[now], 0);
        cluster[now] = now;
        return;
    }
    if (space[now] == flag) {
        for (int i = 1;i <= n;i++) {
            if (space[i] == 0) {
                freespace = i;
                break;
            }
        }
        swap(freespace, flag, now, 0);
        cluster[flag] = freespace;
        swap(now, now, cluster[now], 0);
        cluster[now] = now;
        return;
    }
    dfs(space[now]);
    swap(now, now, cluster[now], 0);
    cluster[now] = now;
    return;
    
}

int main()
{
    int t;
    scanf("%d%d", &n, &t);
    for (int i = 1;i <= n+1;i++) {
        space[i] = 0;
        cluster[i] = 0;
    }
    int a, k = 1, c, num=0;
    for(int i = 0;i < t;i++) {
        scanf("%d", &a);
        num+=a;
        for (int j = 1; j <= a;j++) {
            scanf("%d", &c);
            space[c] = k;
            cluster[k] = c;
            k++;
        }
    }
    for (int i = 1;i <= num;i++) {
        if(space[i] != i) {
            flag = i;
            dfs(i);
        }
    }
    if (flag == -1) {
        printf("No optimization needed\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值