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;
}
时间: 2024-11-08 17:25:59

uva 669(暴力)的相关文章

UVA - 669 Defragment

题意:简单说就是将第i个簇号放回i,求最少的步数 思路:只处理链形,和环形的情况,其他的可以不管,对于链形来说,只要倒置就行了,环形的找一个空闲的放一个,然后就是链形的情况了 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <stack> using namespace std; const int MAXN = 1000

uva 812(暴力)

题意:有n个货架上摆放了b个货物,然后从左到右的给出每个货架上货物买入的价格,要拿去卖掉以统一价10,问如果买入形式是栈,要买一个货物必须把他左边的东西都买了才可以,问最大利润是多少,要买多少个货物达到最大利润,按字典序输出所有可能情况(最多10种). 题解:水题,暴力出所有情况. 第二组样例举例: 3 10 9 10 10 购买数量可能情况:2 4 5 9 17 24 30 30 24 24 30 24 购买数量可能情况: 4 5 8 然后就是6个数字的排列组合相加得到所有解.注意数量可能为0

UVA 11754 (暴力+中国剩余定理)

题目链接: http://www.bnuoj.com/v3/problem_show.php?pid=20172 题目大意:有C个模方程,每个方程可能有k余数,求最小的S个解. 解题思路: 看见模方程就想到中国剩余定理,然后看下确定的方程情况. 由乘法原理,共有II ki 种情况,即求解II ki 次.k比较大时基本完蛋. 其实解模方程还有一种暴力方法,就是选定一个模方程,令t=0,1...., n=t*LCM+余数(n一定要大于0) 通过t不断增大这种迭代方式从小到大创造一些可能解n,然后去测

uva 11127(暴力)

题意:给出一个字符串,包括0.1.*,其中×是可以替换成0或者1的,如果字符串的某个子串S有SSS这样的连续重复3次出现,不是Triple-free串,问给出的字符串可以形成多少个非Triple-free串. 题解:因为串长度最多31,所以可以暴力枚举每一位,边枚举边判断. #include <stdio.h> #include <string.h> const int N = 35; char str[N], str2[N]; int n; long long res; bool

UVA 11464 暴力+位运算 ***

题意:给你一个 n * n 的 01 矩阵,现在你的任务是将这个矩阵中尽量少的 0 转化为 1 ,使得每个数的上下左右四个相邻的数加起来是偶数.求最少的转化个数. 新风格代码 lrj书上说的很清楚了,就是判断下一行的代码有点冗余了,但是很好理解,就是模拟每位有的数字之和,然后判断未知为应该填的数字 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring>

uva 1374(暴力)

题意:给出一个数字x,然后n = 1,每次计算可以让n翻倍,或者加或减之前x计算得过的数,问至少经过几次计算可以让n等于x. 题解:枚举次数,然后dfs是否能在这个次数得到x. #include <stdio.h> const int N = 100; int x, s[N]; bool dfs(int cur, int num, int pre) { if (cur == num && pre == x) return true; if (cur >= num || p

UVa 725暴力求解

A - Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Su Description Write a program that finds and displays all pairs of 5-digit numbers that between them use the digits 0 through 9 once each, such that the first number divided

uva 10570(暴力)

题意:有一个长度为n的序列,数字是从1到n,然后问至少交换多少次可以让序列成为升序或降序的序列,环是升序或降序也可以.比如 2 1 4 3也是可以的. 题解:把从1到n和从n到1所有成立情况放到数组内,共有2×n种情况,然后拿输入的序列和这2n种情况比对,不成功的交换后继续比对,直到完全匹配,找出交换次数最小值. #include <stdio.h> #include <algorithm> using namespace std; const int N = 505; int n

poj 1305

Fermat vs. Pythagoras Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 1450   Accepted: 846 Description Computer generated and assisted proofs and verification occupy a small niche in the realm of Computer Science. The first proof of the