ZOJ-1404

41 篇文章 0 订阅

又是一道超级苦力模拟题。。写了一晚上,蛋碎啊,先求最优策略,然后按题意格式化输出。大意就是找一条横线,使各点到这条横线的距离总和最短,有多种解的情况下,使横线的纵坐标最小。。没什么算法,只能硬写吧。。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>

static int min(int a, int b)
{
	return a < b ? a : b;
}

static int max(int a, int b)
{
	return a > b ? a : b;
}

static int low_bound(int a)
{
	return a % 5 ? a - a % 5 : a - 5;
}

static int high_bound(int b)
{
	return b % 5 ? b - b % 5 + 5 : b + 5;
}

static int distance(int a, int b)
{
	return high_bound(b) - low_bound(a);
}

struct Pair
{
	int x, y;
};

static int cmp(const void *p1, const void *p2)
{
	struct Pair *pp1 = (struct Pair*) p1;
	struct Pair *pp2 = (struct Pair*) p2;
	if (pp1->y != pp2->y)
		return pp1->y - pp2->y;
	else
		return pp1->x - pp2->x;
}

static void print_border(int a, int b)
{
	int i;
	for (i = 0; i < (b - a) / 5; i++)
		printf("+----");
	putchar('+');
	putchar('\n');
}

static void print_low_border(int a, int b)
{
	int i;
	for (i = a; i < b; i += 5)
		printf("%-5d", i);
	printf("%d\n", b);
}

static void print_lead_space(int n)
{
	int i;
	for (i = 0; i < n; i++)
		putchar(' ');
}

int main()
{
	int col, row, count = 1, high[100], low[100];
	char map[100][100];
	struct Pair *array = malloc(20 * sizeof(struct Pair));
	while (scanf("%d %d", &col, &row), col || row)
	{
		int maxc, minc, maxr, minr;
		maxc = minc = col;
		maxr = minr = row;
		printf("OIL FIELD %d\n", count++);
		int index = 0;
		array[index].x = col;
		array[index++].y = row;
		while (scanf("%d %d", &col, &row), col != -1)
		{
			maxc = max(maxc, col);
			minc = min(minc, col);
			maxr = max(maxr, row);
			minr = min(minr, row);
			array[index].x = col;
			array[index++].y = row;
		}
		if (distance(minc, maxc) > 70 || distance(minr, maxr) > 20)
		{
			printf("Map is too big to draw for pipeline at %d\n", minr);
			continue;
		}
		qsort(array, index, sizeof(struct Pair), cmp);
		int i, j, pipe, minlength = INT_MAX;
		for (i = 0; i < index; i++)
		{
			for (j = minc; j <= maxc; j++)
			{
				high[j] = array[i].y;
				low[j] = array[i].y;
			}
			for (j = 0; j < index; j++)
			{
				int x = array[j].x;
				int y = array[j].y;
				high[x] = max(high[x], y);
				low[x] = min(low[x], y);
			}
			int sum = 0;
			for (j = minc; j <= maxc; j++)
				sum += high[j] - low[j];
			if (sum < minlength)
			{
				minlength = sum;
				pipe = array[i].y;
			}
		}
		memset(map, '.', sizeof(map));
		memset(map[pipe], '*', sizeof(map[0]));
		for (i = 0; i < index; i++)
		{
			if (array[i].y > pipe)
				for (j = pipe; j < array[i].y; j++)
					map[j][array[i].x] = '*';
			if (array[i].y < pipe)
				for (j = array[i].y; j < pipe; j++)
					map[j][array[i].x] = '*';
		}
		for (i = 0; i < index; i++)
			map[array[i].y][array[i].x] = '@';

		maxr = high_bound(maxr);
		minr = low_bound(minr);
		maxc = high_bound(maxc);
		minc = low_bound(minc);

		int ls = maxr >= 10 ? 2 : 1;
		printf("%d", maxr);
		print_border(minc, maxc);
		for (i = maxr - 1; i > minr; i--)
		{
			if (i % 5)
				print_lead_space(ls);
			else
				printf(ls == 2 ? "%2d" : "%d", i);
			putchar(i % 5 ? '|' : '+');
			for (j = minc + 1; j < maxc; j++)
				putchar(map[i][j]);
			putchar(i % 5 ? '|' : '+');
			putchar('\n');
		}
		printf(ls == 2 ? "%2d" : "%d", minr);
		print_border(minc, maxc);
		print_lead_space(ls);
		print_low_border(minc, maxc);
	}
	free(array);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值