poj1033

这道题感觉简单,却很容易出错,我真的是想昏了,WA了好多次,好不容易对了吧还TLE,无语了。。。。

1.先把目标位置空闲的块移动目标位置,中间遇到目标位置不空的就存入conflict中有待解决冲突,同时将该块最终的目标位置相应地存入conflict_to,最后再来解决冲突

2.解决冲突时,每空出来一个位置就检测conflict中是不是有目标位置是该位置的块(这个好费时间呀)


#include<iostream>
#include<vector>

using namespace std;

int main()
{
	unsigned n,k;
	unsigned i,j,clusterCnt,noMove;
	
	cin>>n>>k;
	vector<bool> disk(n,false);
	vector<unsigned> usedCluster;
	vector<unsigned> conflict;
	vector<unsigned> conflict_to;
	for(i=0; i<k; ++i)
	{
		cin>>clusterCnt;
		for(j=0; j<clusterCnt; ++j)
		{
			unsigned c;
			cin>>c;
			disk[c-1] = true;//将disk中对应的cluster标记为true
			usedCluster.push_back(c);
		}
	}
	if(usedCluster.size()>=n)
		return -1;
	noMove = 0;
	for(i=0; i<usedCluster.size(); ++i)
	{
		if(disk[i] == false)
		{
			if(usedCluster[i]!=i+1)
			{
				printf("%d %d\n", usedCluster[i], i+1);
				disk[i] = true;
				disk[usedCluster[i]-1] = false;
				for(unsigned m=0; m<conflict.size();)//查找是否有目标位置刚好是刚释放的位置
				{
					if(conflict[m]!=0 && disk[conflict_to[m]-1] == false)
					{
						printf("%d %d\n", conflict[m], conflict_to[m]);
						disk[conflict[m]-1] = false;
						disk[conflict_to[m]-1] = true;
						conflict[m] = 0;
						m=0;
					}
					else
						++m;
				}
			}
			else
				noMove++;
				
		}
		else
		{
			if(usedCluster[i]!=i+1)
			{
				conflict.push_back(usedCluster[i]);//from
				conflict_to.push_back(i+1);//to,将要去的cluster
			}
			else
				noMove++;
		}
	}

	for(i=0; i<conflict.size(); ++i)
	{
		if(conflict[i]!=0)
		{
			if(disk[conflict_to[i]-1]==false)//目的cluster未使用
			{
				printf("%d %d\n", conflict[i], conflict_to[i]);
				disk[conflict[i]-1] = true;
				disk[conflict_to[i]-1] = false;
				conflict[i] = 0;
				for(unsigned m=0; m<conflict.size();)//查找是否有目标位置刚好是刚释放的位置
				{
					if(conflict[m]!=0 && disk[conflict_to[m]-1] == false)
					{
						printf("%d %d\n", conflict[m], conflict_to[m]);
						disk[conflict[m]-1] = false;
						disk[conflict_to[m]-1] = true;
						conflict[m] = 0;
						m=0;
					}
					else
						++m;
				}
			}
			else
			{
				for(j=disk.size()-1; j>=0; --j)//从磁盘末尾向前找第一个为空的位置
				{
					if(disk[j]==false)
						break;
				}
				if(j>0)//找到空的位置
				{
					printf("%d %d\n", conflict[i], j+1);
					disk[conflict[i]-1] = false;
					disk[j] = true;
					conflict[i] = j+1;
					for(unsigned m=0; m<conflict.size();)//查找是否有目标位置刚好是刚释放的位置
					{
						if(conflict[m]!=0 && disk[conflict_to[m]-1] == false)
						{
							printf("%d %d\n", conflict[m], conflict_to[m]);
							disk[conflict[m]-1] = false;
							disk[conflict_to[m]-1] = true;
							conflict[m] = 0;
							m=0;
						}
						else
							++m;
					}
				}
				i=0;
			}
		}
	}
	if(noMove == usedCluster.size())
		cout<<"No optimization needed"<<endl;
	return 0;
}


参考:http://blog.youkuaiyun.com/kindlucy/article/details/7447855,用一个栈来保存冲突的块


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值