首页 > 代码库 > seartch1033

seartch1033

点评:此题的通过率看起来挺吓人的,其实也不难。

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

 

  文件12 3 11 12,占用了4个簇,编号为1-4
  文件27,占用了1个簇,编号为5

  文件318 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]不满足12,则又有两种情况。

    情况一:磁盘使用情况成链:如图所示:

    

    簇号:  1  2  3  4  5  6 ...     

    逻辑编号:5  0  4  2  3  0 ...

         即clusters[1]=4 clusters[2]=0 c[3]=3 c[4]=1 c[5]=2

 实际上,一定有某个c[i]=1,这里暂且不论,只讨论栈问题

     第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,则需要输出一行信息。

 

 

 

自己通过的:#include<cstdio>#include<stack>#include<cstring>using std::stack;stack<unsigned short> s;int main(){			int count,i,j,k,l,temp;	unsigned short c[10001];	int num_cluster,num_file,num;	bool ok=0;	while(scanf("%d%d",&num_cluster,&num_file)!=EOF)	{	memset(c,0,sizeof(c));	count=1;	for(i=1;i<=num_file;i++)	{		scanf("%d",&num);		for(j=1;j<=num;j++)		{			scanf("%d",&temp);			c[temp]=count++;		}	}	for(i=1;i<=num_cluster;i++)	{		if(c[i]!=0 && c[i]!=i)		{			ok=1;			j=c[i];			s.push(i);			while(c[j]!=0 && c[j]!=i)			{				s.push(j);				j=c[j];			}			if(c[j]!=i)			{					while(!s.empty())				{					k=s.top();					s.pop();					c[j]=c[k];					c[k]=0;					printf("%d %d\n",k,j);					j=k;				}			}			else			{				for(l=num_cluster;l>=1;l--)					if(c[l]==0)						break;				c[l]=c[j];				printf("%d %d\n",j,l);				while(!s.empty())				{					k=s.top();					s.pop();					c[j]=c[k];					c[k]=0;					printf("%d %d\n",k,j);					j=k;				}								c[j]=c[l];				c[l]=0;//麻痹啊就是少了这一句导致一直不通过				printf("%d %d\n",l,j);			}		}	}	if(!ok)	printf("No optimization needed\n");	}return 1;	}

 

  

 

seartch1033