这道题感觉简单,却很容易出错,我真的是想昏了,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,用一个栈来保存冲突的块