UVa209 - Triangular Vertices(几何)

 Consider the points on an infinite grid of equilateral triangles as shown below:

Note that if we number the points from left to right and top to bottom, then groups of these points form the vertices of certain geometric shapes. For example, the sets of points {1,2,3} and {7,9,18} are the vertices of triangles, the sets {11,13,26,24} and {2,7,9,18} are the vertices of parallelograms, and the sets {4,5,9,13,12,7} and {8,10,17,21,32,34} are the vertices of hexagons.

Write a program which will repeatedly accept a set of points on this triangular grid, analyze it, and determine whether the points are the vertices of one of the following ``acceptable" figures: triangle, parallelogram, orhexagon. In order for a figure to be acceptable, it must meet the following two conditions:

 
		1)	Each side of the figure must coincide with an edge in the grid.

and 2) All sides of the figure must be of the same length.

Input

The input will consist of an unknown number of point sets. Each point set will appear on a separate line in the file. There are at most six points in a set and the points are limited to the range 1..32767.

Output

For each point set in the input file, your program should deduce from the number of points in the set which geometric figure the set potentially represents; e.g., six points can only represent a hexagon, etc. The output must be a series of lines listing each point set followed by the results of your analysis.

Sample Input

1 2 3
11 13 29 31
26 11 13 24
4 5 9 13 12 7
1 2 3 4 5
47
11 13 23 25

Sample Output

1 2 3 are the vertices of a triangle
11 13 29 31 are not the vertices of an acceptable figure
26 11 13 24 are the vertices of a parallelogram
4 5 9 13 12 7 are the vertices of a hexagon
1 2 3 4 5 are not the vertices of an acceptable figure
47 are not the vertices of an acceptable figure
11 13 23 25 are not the vertices of an acceptable figure

题意:给出n个点(最多6个),判断是等边三角形、菱形还是正六边形,要求构成的边是图中的虚线部分。
思路:将对应的点的序号转换成坐标。横坐标中的两个单位对应纵坐标的一个单位。在判断构成的边是否是虚线部分,如果y坐标相等,说明是的,还有一种情况,两个点的横坐标、纵坐标的差的绝对值相等。
在判断菱形时,有两种情况:(1)只有两层,每层有两个点; (2)由三层组成,第一层有一个点,第二层有两个点,第三层有一个点
在判断正六边形时,只有一种情况,即有三层,每层两个点,第一层两点距离等于第三层两点的距离,而第二层两点间的距离是第一层的两倍

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAXN = 32770;
const int MAXNUM = 6;
const int BUFLEN = 128;

struct Point
{
	int x, y;
}points[MAXN];

int num[MAXNUM];
int n;

bool cmpx(const Point &a, const Point &b)
{
	return a.x < b.x;
}

bool cmpy(const Point &a, const Point &b)
{
	return a.y < b.y;
}

void init()
{
	int curx = 0, cury = 0;
	int dep = 0;
	int numOfDep = 1;

	for (int i = 1; i < MAXN; i++) {
		points[i].x = curx;
		points[i].y = cury;
		numOfDep--;

		if (numOfDep == 0) {
			dep++;
			numOfDep = dep + 1;
			curx = -dep;
			cury++;
		} else {
			curx += 2;
		}
	}
}

bool input()
{
	char buf[BUFLEN];

	if (fgets(buf, BUFLEN, stdin) == NULL) return false;
	n = sscanf(buf, "%d%d%d%d%d%d", &num[0], &num[1], &num[2], &num[3], &num[4], &num[5]);

	return true;
}

bool is_coincide(const Point &a, const Point &b)
{
	if (a.x == b.x && a.y == b.y) return false;

	if (a.y == b.y) return true;
	else {
		int dx = abs(a.x - b.x);
		int dy = abs(a.y - b.y);

		if (dx == dy) return true;
		else return false;
	}
}

int dis(const Point &a, const Point &b)
{
	if (a.x == b.x && a.y == b.y) return 0;

	if (a.y == b.y) {
		return abs(a.x - b.x) >> 1;
	} else {
		int dx = abs(a.x - b.x);
		int dy = abs(a.y - b.y);

		if (dx == dy) return dx;
		else return 0;
	}
}


bool check_triangle()
{
	if (is_coincide(points[num[0]], points[num[1]])
		&& is_coincide(points[num[0]], points[num[2]])
		&& is_coincide(points[num[1]], points[num[2]])) {
			int len = dis(points[num[0]], points[num[1]]);
			if (dis(points[num[0]], points[num[2]]) == len
				&& dis(points[num[1]], points[num[2]]) == len) return true;
	}

	return false;
}

bool check_parallelogram()
{
	Point tmpPoint[4];
	for (int i = 0; i < n; i++) {
		tmpPoint[i] = points[num[i]];
	}

	sort(tmpPoint, tmpPoint + 4, cmpy);

	if (tmpPoint[0].y == tmpPoint[1].y && tmpPoint[2].y == tmpPoint[3].y && tmpPoint[1].y != tmpPoint[2].y) {
		sort(tmpPoint, tmpPoint + 2, cmpx);
		sort(tmpPoint + 2, tmpPoint + 4, cmpx);
		int d1 = dis(tmpPoint[0], tmpPoint[1]);
		int d2 = dis(tmpPoint[2], tmpPoint[3]);
		if (!is_coincide(tmpPoint[0], tmpPoint[2])) return false;
		int d3 = dis(tmpPoint[0], tmpPoint[2]);
		if (!is_coincide(tmpPoint[1], tmpPoint[3])) return false;
		int d4 = dis(tmpPoint[1], tmpPoint[3]);
		if (d1 != 0 && d1 == d2 && d2 == d3 && d3 == d4) return true;
		return false;
	}

	if (tmpPoint[0].y != tmpPoint[1].y && tmpPoint[1].y == tmpPoint[2].y && tmpPoint[2].y != tmpPoint[3].y) {
		sort(tmpPoint + 1, tmpPoint + 3, cmpx);
		if (!is_coincide(tmpPoint[0], tmpPoint[1])) return false;
		int d1 = dis(tmpPoint[0], tmpPoint[1]);
		if(!is_coincide(tmpPoint[0], tmpPoint[2])) return false;
		int d2 = dis(tmpPoint[0], tmpPoint[2]);
		if(!is_coincide(tmpPoint[1], tmpPoint[3])) return false;
		int d3 = dis(tmpPoint[1], tmpPoint[3]);
		if(!is_coincide(tmpPoint[2], tmpPoint[3])) return false;
		int d4 = dis(tmpPoint[2], tmpPoint[3]);
		int d5 = dis(tmpPoint[1], tmpPoint[2]);

		if (d1 != 0 && d1 == d2 && d2 == d3 && d3 == d4 && d4 == d5) return true;
		return false;
	}

	return false;
}

bool check_hexagon()
{
	Point tmpPoint[6];
	for (int i = 0; i < n; i++) {
		tmpPoint[i] = points[num[i]];
	}

	sort(tmpPoint, tmpPoint + 6, cmpy);

	if (tmpPoint[0].y == tmpPoint[1].y && tmpPoint[1].y != tmpPoint[2].y && 
		tmpPoint[2].y == tmpPoint[3].y && tmpPoint[3].y != tmpPoint[4].y && 
		tmpPoint[4].y == tmpPoint[5].y) {
			sort(tmpPoint, tmpPoint + 2, cmpx);
			sort(tmpPoint + 2, tmpPoint + 4, cmpx);
			sort(tmpPoint + 4, tmpPoint + 6, cmpx);
			int d1 = dis(tmpPoint[0], tmpPoint[1]);
			if(!is_coincide(tmpPoint[0], tmpPoint[2])) return false;
			int d2 = dis(tmpPoint[0], tmpPoint[2]);
			if(!is_coincide(tmpPoint[1], tmpPoint[3])) return false;
			int d3 = dis(tmpPoint[1], tmpPoint[3]);
			if(!is_coincide(tmpPoint[2], tmpPoint[4])) return false;
			int d4 = dis(tmpPoint[2], tmpPoint[4]);
			if(!is_coincide(tmpPoint[3], tmpPoint[5])) return false;
			int d5 = dis(tmpPoint[3], tmpPoint[5]);
			int d6 = dis(tmpPoint[4], tmpPoint[5]);
			int d7 = dis(tmpPoint[2], tmpPoint[3]);

			if (d1 != 0 && d1 == d2 && d2 == d3 && d3 == d4 && d4 == d5 && d5 == d6 && d7 == 2 * d6) return true;
			return false;
	} 

	return false;
}

void solve()
{
	if (!(n == 3 || n == 4 || n == 6)) {
		for (int i = 0; i < n; i++) {
			printf("%d ", num[i]);
		}
		printf("are not the vertices of an acceptable figure\n");
		return;
	}

	for (int i = 0; i < n; i++) {
		printf("%d ", num[i]);
	}

	if (n == 3) {
		if (check_triangle()) {
			printf("are the vertices of a triangle\n");
			return;
		} else {
			goto no;
		}
	}

	if (n == 4) {
		if (check_parallelogram()) {
			printf("are the vertices of a parallelogram\n");
			return;
		} else {
			goto no;
		}
	}

	if (n == 6) {
		if (check_hexagon()) {
			printf("are the vertices of a hexagon\n");
			return;
		} else {
			goto no;
		}
	}

no:
	printf("are not the vertices of an acceptable figure\n");
}

int main(int argc, char **argv)
{
#ifndef ONLINE_JUDGE
	freopen("d:\\OJ\\uva_in.txt", "r", stdin);
#endif // ONLINE_JUDGE

	init();

	while (input()) {
		solve();
	}

	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值