参考: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