HZOJ-285:序列M小和(c语言)

#include 
#include 
#define cmp >

void swap(int* a, int* b) {
	int t = *a;
	*a = *b;
	*b = t;
	return;
}

void merge(int* arr, int l, int r) {
	if (r - l < 2) return;
	int mid = (l + r) / 2;
	merge(arr, l, mid);
	merge(arr, mid, r);
	int* temp = (int*)malloc(sizeof(int) * (r - l));
	int p1 = l, p2 = mid, k = 0;
	while (p1 < mid || p2 < r) {
		if (p2 == r || (p1 < mid && arr[p1] < arr[p2])) {
			temp[k++] = arr[p1++];
		}
		else temp[k++] = arr[p2++];
	}
	for (int i = l; i < r; i++) arr[i] = temp[i - l];
	free(temp);
	return;
}


void down_updata(int* _arr, int i, int n) {
	int* arr = _arr - 1;
	while (i * 2 <= n) {
		int ind = i, l = i * 2, r = l + 1;
		if (arr[l] cmp arr[ind]) ind = l;
		if (r <= n && arr[r] cmp arr[ind]) ind = r;
		if (ind == i) return;
		swap(&arr[ind], &arr[i]);
		i = ind;
 	}
	return;
}


int main() {
	int n, m;
	scanf("%d %d", &n, &m);
	int** arr = (int**)malloc(sizeof(int*) * 2);
	arr[0] = (int*)malloc(sizeof(int) * m);
	arr[1] = (int*)malloc(sizeof(int) * m);
	for (int i = 0; i < m; i++) scanf("%d", &arr[0][i]);

	//建大顶堆
	for (int i = m / 2; i >= 1; i--) 
		down_updata(arr[0], i, m);

	for (int i = 1; i < n; i++) {
		int l = i % 2, r = (l + 1) % 2, num; //滚动数组
		for (int j = 0; j < m; j++) {
			scanf("%d", &num);
			if (!j) {
				for (int k = 0; k < m; k++)
					arr[l][k] = num + arr[r][k];
				continue;
			}
			for (int k = 0; k < m; k++) {
				if (num + arr[r][k] < arr[l][0]) {
					arr[l][0] = num + arr[r][k];
					down_updata(arr[l], 1, m);
				}
			}
		}
	}

	int l = (n - 1) % 2;
	merge(arr[l], 0, m);
	for (int i = 0; i < m; i++) {
		if (i) printf(" ");
		printf("%d", arr[l][i]);
	}
	free(arr);
	return 0;
}

你可能感兴趣的:(算法题,算法)