hdu1033Defragment

参考:http://blog.csdn.net/ll365594480/article/details/6843449

【题意】磁盘分为N个簇,一个文件可以占用K个簇,(1 <= K < N <= 10000),给出各个文件的占用磁盘的情况,也就是一个文件占用了哪些簇,想要进行碎片整理,就是把这些簇按顺序整理到磁盘的最顶部。

初始状态是这样的,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

【思路】先判断该位置是否为空,为空就直接移动,如果不为空的话,判断是否成环,如果成环的话,就领取一个空点,把其中一个移入,用栈处理会比较方便。

#include<iostream>
#include<stdio.h>
#include<stack>
#include<string.h>
using namespace std;
const int N=10000+10;
int vis[N];
int n,m,k;
stack<int>st;
int cnt=1;

void solve()
{
    int next,i,move_num=0;
    for(i=1;i<=n;i++)
    {
        if(vis[i]==i) continue;
        else if(vis[i]!=0)
        {
            st.push(i);
            next=vis[i];
            bool flag;
            while(1)
            {
                if(vis[next]==i)
                {
                    flag=true;
                    break;
                }
                else if(vis[next]==0)
                {
                    flag=false;
                    break;
                }
                st.push(next);
                next=vis[next];
            }
            if(flag)
            {
                int j;
                for(j=n;j>=0;j--)
                {
                    if(vis[j]==0)
                        break;
                }
                vis[j]=vis[next];
                printf("%d %d\n",next,j);
                while(!st.empty())
                {
                    int top=st.top();
                    vis[next]=vis[top];
                    printf("%d %d\n",top,next);
                    st.pop();
                    next=top;
                    move_num++;
                }
                vis[next]=vis[j];
                vis[j]=0;
                printf("%d %d\n",j,next);
            }
            else
            {
                while(!st.empty())
                {
                    int top=st.top();
                    vis[next]=vis[top];
                    printf("%d %d\n",top,next);
                    st.pop();
                    next=top;
                    move_num++;
                }
                vis[next]=0;
            }
        }
    }
    if(move_num==0)
        printf("No optimization needed\n");
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        cnt=1;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&k);
            for(int j=1;j<=k;j++)
            {
                int x;
                scanf("%d",&x);
                vis[x]=cnt++;
            }
        }
        solve();
    }
    return 0;
}
时间: 2024-10-21 04:07:40

hdu1033Defragment的相关文章