uva 669(贪心)

题意:有连续n块内存,然后有k个文件,每个文件可以分为ki块放到内存里,其他内存块为空,现在给出每个文件的ki个碎片在内存中的放在第几块(碎片有序),然后开始进行内存块内容的移动,操作a b表示把内存a中的东西放到内存b中,前提是b为空,要求最少的操作使文件能够按顺序从最小的内存块开始存储,输出顺序操作过程。

题解:用一个flag[i] = j表示位置i上放的碎片应该放到位置j上,可以先遍历一遍把能放碎片的先放,然后开始循环,挑出一个摆放不正确的位置,把碎片放到空闲位置,然后循环遍历把能放到正确位置的碎片放到正确位置,直到全部都对。

#include <stdio.h>
#include <string.h>
const int N = 10005;
int n, k, flag[N], num;

bool judge() {
	for (int i = 1; i <= num; i++)
		if (flag[i] != i)
			return false;	
	return true;
}

void solve() {
	int c = 0;
	while(1) {
		int cc = c;
		for (int i = 1; i <= num; i++) {
			if (!flag[i]) {
				for (int j = 1; j <= n; j++)
					if (flag[j] == i) {
						c++;
						printf("%d %d\n", j, i);
						flag[i] = i;
						flag[j] = 0;
						break;
					}
			}
		}
		if(c == cc)
			break;
	}
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &n, &k);
		memset(flag, 0, sizeof(flag));
		int	temp, a;
		num = 0;
		for (int i = 0; i < k; i++) {
			scanf("%d", &temp);
			for (int j = 0; j < temp; j++) {
				scanf("%d", &a);
				flag[a] = ++num;
			}
		}
		if (judge())
			printf("No optimization needed\n");
		else {
			solve();
			while (1) {
				for (int i = 1; i <= num; i++) {
					if (flag[i] && flag[i] != i) {
						for (int j = num + 1; j <= n; j++)
							if (!flag[j]) {
								printf("%d %d\n", i, j);
								flag[j] = flag[i];
								flag[i] = 0;
								break;
							}
						break;
					}
				}
				solve();
				if (judge())
					break;
			}
		}
		if (t)
			printf("\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值