题意:
给出n个空间,标号1到n;
给出k个文件;
每个文件给出要占几个空间,并且给出占的空间有哪些;
现在要我们按顺序,把这些文件排好;
比如三个文件,分别占空间个数4,3,2;
那么第一个文件就要放到空间1,2,3,4,第二个文件放到5,6,7第三个文件放到8,9;
问怎么移动,要求移动最少;
思路;
暴力;
一.把所有能移动到正确位置的部分全都移动到正确位置(就是这个部分放的位置不对,而且它正确的的那个位目前是空的)
二.已经没有办法移了,然后随便拿一个位置放错的,放到一个空位(这样肯定就可以继续移了),然后继续执行上面的第一步;
知道正确为止;
如果一开始就正确;输出No optimization needed
#include<cstdio>
#include<cstring>
const int N = 10005;
int clus[N], cnt, n, k, make;
void solve() {
int c = 0;
while(1) {
int cc = c;
for(int i = 1; i <= n;i++) {
if(clus[i] != i && clus[i] != 0 && clus[clus[i]] == 0) {
c++;
printf("%d %d\n",i,clus[i]);
clus[clus[i]] = clus[i];
clus[i] = 0;
}
}
if(c == make)
break;
if(cc == c) {
bool f = 0;
for(int i = 1; i <= n; i++) {
if(clus[i] != i && clus[i] != 0) {
for(int j = 1; j <= n ;j++) {
if(clus[j] == 0) {
printf("%d %d\n",i,j);
clus[j] = clus[i];
clus[i] = 0;
f = 1;
break;
}
}
}
if(f)
break;
}
}
}
}
int main() {
int t;
scanf("%d",&t);
while(t--) {
memset(clus, 0, sizeof(clus));
make = 0;
scanf("%d%d",&n,&k);
cnt = 1;
for(int i = 1; i <= k; i++) {
int c;
scanf("%d",&c);
int tmp;
for(int i = 0; i < c;i++) {
scanf("%d",&tmp);
clus[tmp] = cnt++;
if(tmp != cnt - 1)
make++;
}
}
if(make == 0)
printf("No optimization needed\n");
solve();
if(t)
printf("\n");
}
}