POJ 1033 Defragment(模拟)

4 篇文章 0 订阅

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

思路

题中说的一个文件几个部分没有用,就把每一个部分当成一个文件就行。i号文件放到i号位,用最短的步骤移动到全都正确
详见代码注释

代码

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;

int a[10005];						//存储一个文件现有的位置 
int vis[10005];						//存储一个位置是否被占用 
int ok[10005];						//一个文件存储是否正确 
queue<int>save;						//所有位置不对文件的下标 

int main()
{
	int n,k,m;
	cin>>n>>k;
	int cnt=0,num=0;
	while(k--)
	{
		scanf("%d",&m);
		num+=m;
		while(m--)
		{
			scanf("%d",&a[++cnt]);
			vis[a[cnt]]=1;
		}
	}
	int mov=0;
	for(int i=1;i<=num;i++)
	{
		if(a[i]==i)					//a[i]=i说明位置是对的 
		{
			ok[i]=1;
			continue;
		}
		if(!vis[i])					//本来的位置不对,但正确位置是空的 将其放到正确位置 
		{
			cout<<a[i]<<" "<<i<<endl;	//只能先输出,在变位置,要不之前位置就不知道了 
			mov++;
			vis[a[i]]=0;				//原位置清空 
			vis[i]=1;					//新位置标记 
			a[i]=i;
			ok[i]=1;					//存好标记 
		}
		else
			save.push(i);				//位置错的记录下来 
	}
	while(save.size())
	{
		int t,i;		
		t=save.front();
		if(ok[t])
		{
			save.pop();					//如果存好了,弹出 
			continue;
		}
		if(!vis[t])
		{
			cout<<a[t]<<" "<<t<<endl;
			vis[t]=1;
			vis[a[t]]=0;				//正确位置是空的,就存入 
			ok[t]=1;					//此时无法弹出,因为不一定 
			a[t]=t;
			mov++;
			save.pop(); 			
			continue;
		}
		if(a[t]>num)
		{
			save.pop();					//存的位置大于num,无用,不需空出 
			save.push(t);				//先弹出,再放在队尾,等着它的位置空了
			continue;				 	//以上处理完都要继续下一个 
		}
		for(i=n;i&&vis[i];i--);			//找一个没有用到的位置,作中转  腾出现有位置 
		cout<<a[t]<<" "<<i<<endl;
		vis[a[t]]=0;					//转移过程同上 
		a[t]=i;
		vis[i]=1;
		mov++;
		save.pop();			
		save.push(t);					//放队尾 
		cout<<a[tmp]<<" "<<tmp<<endl;	//将正确的文件放到刚腾出的位置
		vis[a[tmp]]=0;
		vis[tmp]=1;
		ok[tmp]=1;
		a[tmp]=tmp;
	}
	if(mov==0)
		cout<<"No optimization needed";	//未移动 
	return 0;
}

代码感觉没有什么问题,查了好多遍,但是WA。各位大佬帮我看看。orz

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值