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