ACM 算法艺术与信息学竞赛 1.2.1盒子里面的汽球

原创 2011年10月24日 21:58:42

盒子里面的汽球

题目大意我就不多说了,直看一下刘汝佳的书。这里给出链接,与我出错的总结

盒子里的汽球

Problem 1515 Balloons in a Box

Accept: 171    Submit: 919
Time Limit: 1000 mSec    Memory Limit : 32768 KB

Problem Description

You must write a program that simulates placing spherical balloons into a rectangular box.

The simulation scenario is as follows. Imagine that you are given a rectangular box and a set of points inside the box. Each point represents a position where you might place a balloon. To place a balloon at a point, center it at the point and inflate the balloon until it touches a side of the box or a previously placed balloon. You may use the points in any order you like, and need not use every point. Your objective is to place balloons in the box in an order that maximizes the total volume occupied by the balloons.

You are required to calculate the volume within the box that is not enclosed by the balloons.

All integer will be in [-1000, 1000].

Input

The input consists of several test cases. The first line of each test case contains a single integer n that indicates the number of points in the set (n ≤ 6). The second line contains three integers that represent the (x, y, z) integer coordinates of a corner of the box, and the third line contains the (x, y, z) integer coordinates of the opposite corner of the box. The next n lines of the test case contain three integers each, representing the (x, y, z) coordinates of the points in the set. The box has non-zero length in each dimension and its sides are parallel to the coordinate axes.

Output

For each test case print one line which indicates the volume of the box not occupied by balloons. Round the volume to the nearest integer.

Sample Input

2 0 0 0 10 10 10 3 3 3 7 7 7

Sample Output

774

Source

FZU 2007 ICPC Qualification Round I


出错总结

1、用GNU C 提交,但是加了//为注释

2、在查看别的点的时候,如果别的点的半径为0,可需要直接跳过

			for (j = 0; j < n; ++j)
			{
				iter = ret[j]; mind = INF;
				for (k = 0; k < n; ++k)
				{
					if (k == iter) continue;  ->改为 if (k == iter || radius[k] == 0) continue;
					d = D[iter][k] - radius[k];
					mind = min(d, mind);
				}
				radius[iter] = min(mind, defined[iter]);
			}
3、可能福州里面使用的编译器版本比较老,我用while语句会出错,但是改成for则没有问题。

void _get_number(int v, const int n)
{
	int idx = 1, now_value = n, iter = n, pos, cnt = -1, j;
	memset(rec, 0, sizeof(rec));
	memset(ret, 0, sizeof(ret));

	do 
	{
		rec[idx] = v % (idx + 1);
		v /= ++idx;
	} while (v);

	while (--iter && --now_value)  ->改为 for (iter = now_value = MAXN -1; iter > 0; --iter, --now_value)
	{
		pos = rec[iter];
		for (cnt = -1, j = n - 1; j >= 0 && cnt != pos; --j) cnt += 0 == ret[j];
		ret[j + 1] = now_value;
	}
}
4、此外,坐标值最好用double来表示。(让我错了无数次,郁闷)

5、四舍五入的处理用printf("%.0lf\n", V);可以实现四舍五入的效果。

附上代码吧,这里用的是枚举的思路来处理的。不知道有没有更好的思路

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

#define  MM 100
const double PI = 3.1415926535;
const double INF = 2147364735.0;
#define  min(a, b)  ((a) > (b) ? (b) : (a))
#define  max(a, b)  ((a) > (b) ? (a) : (b))
#define  abso(a) ((a) > 0 ? (a) : 0 - (a))
const int frac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};

typedef struct _node
{
	double x, y, z;
}node;


node point[MM], from, to;
double D[MM][MM];
double R[MM];
int rec[MM];
int ret[MM];
void _get_number(const int v, const int MAXN)
{
	int idx = 1, iter = MAXN, pos, cont, j;
	int value = v;
	memset(rec, 0, sizeof(rec));
	memset(ret, 0, sizeof(ret));

	do
	{
		rec[idx] = value % (idx + 1);
		value /= ++idx;
	} while (value);

	for (iter = MAXN - 1; iter > 0; --iter)
	{
		pos = rec[iter];
		for (cont = -1, j = MAXN - 1; j >= 0; --j)
		{
			if (0 == ret[j])
			{
				++cont;
				if (pos == cont) { ret[j] = iter; break;}
			}
		}
	}
}

double _dist(int i, int j)
{
	double a = point[i].x - point[j].x;
	double b = point[i].y - point[j].y;
	double c = point[i].z - point[j].z;
	return sqrt(a * a + b * b + c * c);
}

double _min_dist(int i)
{
	double t;
	double f = point[i].x - from.x, s = to.x - point[i].x; 
	f = abso(f); s = abso(s); t = min(f, s);

	f = point[i].y - from.y; s = to.y - point[i].y; 
	f = abso(f); s = abso(s); t = min(f, t); t = min(s, t);

	f = point[i].z - from.z; s = to.z - point[i].z; 
	f = abso(f); s = abso(s); t = min(f, t); t = min(s, t);

	return t;
}


int main(void)
{
	int n, i, j, k, next, iter;
	double V, minR, sumV, maxV, d;
	while (scanf("%d", &n) != EOF)
	{
		scanf("%lf%lf%lf%lf%lf%lf", &(from.x), &(from.y), &(from.z), &(to.x), &(to.y), &(to.z));
		V = (to.x - from.x) * (to.y - from.y) * (to.z - from.z); V = abso(V);

		for (i = 0; i < n; ++i) scanf("%lf%lf%lf", &(point[i].x), &(point[i].y), &(point[i].z));
		for (i = 0; i < n; ++i) 
			for (D[i][i] = _min_dist(i), j = i + 1; j < n; ++j) 
				D[i][j] = D[j][i] = _dist(i, j);

		for (maxV = next = 0; next < frac[n]; ++next)
		{
			memset(R, 0, sizeof(R));
			_get_number(next, n);

			for (sumV = i = 0; i < n; ++i)
			{
				iter = ret[i]; minR = INF;
				for (k = 0; k < n; ++k)
				{
					if (k != iter && R[k] > 0)
					{
						d = D[iter][k] - R[k];
						if (d <= 0) { minR = 0; break;}
						else minR = min(minR, d);
					}
				}
				minR = min(minR, D[iter][iter]); R[iter] = minR;
				sumV += 4.0 * PI * minR * minR * minR / 3.0;
			}
			maxV = max(maxV, sumV);
		}
		printf("%.0lf\n", V - maxV);
	}
	return 0;
}


《算法艺术与信息学竞赛》例题1.2.1——盒子里的气球(fzu1515)

黑书上面的第一个问题,写了很久,又参考了网上的代码。算法的思想是枚举。 首先截图题目如下: oj上面的题目在http://acm.fzu.edu.cn/problem.php?pid=15...
  • jyNext
  • jyNext
  • 2012年08月30日 11:42
  • 1531

ACM 算法艺术与信息学竞赛 1.2.1 图书馆

这个题在POJ和URAL上都可以找到。下面给出链接 ural-1188 PKU-1116 下面还是把题目粘一下 Library Time Limit: 1...
  • ju136
  • ju136
  • 2011年10月25日 20:51
  • 1001

ACM题目推荐--《算法艺术与信息学竞赛》

ACM题目推荐--《算法艺术与信息学竞赛》2008-09-04 12:21一.动态规划 参考资料: 刘汝佳《算法艺术与信息学竞赛》 《算法导论》 推荐题目: http://acm.pku...

ACM 算法艺术与信息学竞赛 1.2.4 售货员

题目就不去多说了,就是说有两个浮点数P, Q,给一个整数,使得(P*x, Q*x)之间一定有一个整数,注意了,是不包含P*x, Q*x这两个数的。 看起来也比较简单。 题目链接 售货员 我这个...
  • ju136
  • ju136
  • 2011年10月25日 20:57
  • 701

【ACM训练计划】 《算法艺术与信息学竞赛》题目出处 (POJ等)

一.动态规划 参考资料: 刘汝佳《算法艺术与信息学竞赛》 《算法导论》 推荐题目: http://acm.pku.edu.cn/JudgeOnline/problem?id=1141 简单 ht...

ACM 算法艺术与信息学竞赛 -刘汝佳

  • 2017年12月03日 16:43
  • 28.99MB
  • 下载

《算法艺术与信息学竞赛》题目-提交方式对照表

id   title how2submit source page 1   盒子里的气球     8 2   图书馆 ural1188   9 ...
  • xxx0624
  • xxx0624
  • 2013年08月04日 10:55
  • 874

《算法艺术与信息学竞赛》题目-提交方式对照表

id   title how2submit source page 1   盒子里的气球     8 2   图书馆 ural1188   9 ...

《算法艺术与信息学竞赛》之 队列 例一 UVa 239 - Tempus et mobilius. Time and motion

算法艺术与信息学竞赛
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ACM 算法艺术与信息学竞赛 1.2.1盒子里面的汽球
举报原因:
原因补充:

(最多只允许输入30个字)