【DFS】【数论】Kc看星(star)

L i n k Link Link

s s l   1496 ssl\ 1496 ssl 1496

D e s c r i p t i o n Description Description

“一闪一闪亮晶晶,满天都是小星星”

Kc吟唱着歌谣,躺在草坪上边想着她边看起了星星。Kc刚刚结识了笛卡尔这位好基友,认为他的坐标系非常神奇。于是他随机地选出了8颗星星,并且给它们标上了坐标。Kc又不甘寂寞,于是思考起一个问题:这八个点能否恰好构成一个正方形和一个矩形呢?

I n p u t Input Input

输入文件包括1行16个数,表示8个星星的坐标,坐标绝对值不超过10000。

O u t p u t Output Output

输出文件第一行是"YES"或者"NO"。表示是否有解。

若有解则第二行依次输出正方形每个顶点的序号。第三行依次输出矩形每个顶点的序号。序号即为输入的顺序。

另外注意:因为kc是一个刁端的人,所以他要求第二行和第三行这八个数要字典序最小。

四点共线不能认为是正方形或矩形

S a m p l e Sample Sample I n p u t Input Input

0 0 10 11 10 0 0 11 1 1 2 2 2 1 1 2

S a m p l e Sample Sample O u t p u t Output Output

YES
5 6 7 8
1 2 3 4

S o l u t i o n Solution Solution

emm比赛的时候瞎写写了个寂寞
其实就是 d f s dfs dfs出所有全排列,然后判断是否是正方形或者是矩形
正方形就判断四边是否相等以及对角线是否相等
矩形就是判断对边是否相等以及对角线是否相等
预处理一下点与点之间的距离

C o d e Code Code

#include
#include
#include
#include

using namespace std;

bool c[10];
int x[10], y[10];
int dis[10][10], a[10];

void check()
{
	if (dis[a[1]][a[2]] != dis[a[2]][a[3]]) return;
	if (dis[a[1]][a[2]] != dis[a[2]][a[3]]) return;
	if (dis[a[3]][a[4]] != dis[a[4]][a[1]]) return;
	if (dis[a[1]][a[3]] != dis[a[2]][a[4]]) return;//判断是否是正方形
	
	if (dis[a[5]][a[6]] != dis[a[7]][a[8]]) return;
	if (dis[a[5]][a[8]] != dis[a[6]][a[7]]) return;
	if (dis[a[5]][a[7]] != dis[a[6]][a[8]]) return;//判断是否是矩形
	
	sort(a + 1, a + 4 + 1);
	sort(a + 5, a + 8 + 1);//排序后字典序最小
	printf("YES\n");
	for (int i = 1; i <= 4; ++i)
		printf("%d ", a[i]);
	printf("\n");
	for (int i = 5; i <= 8; ++i)
		printf("%d ", a[i]);
	exit (0);
}

void dfs(int s)
{
	if (s > 8) {
		check();
		return;
	}
	else {
		for (int i = 1; i <= 8; ++i)
		{
			if (!c[i])
			{
				c[i] = 1;
				a[s] = i;
				dfs(s + 1);
				c[i] = 0;
			}
		}
	}
}

int main()
{
	for (int i = 1; i <= 8; ++i)
		scanf("%d%d", &x[i], &y[i]);
	for (int i = 1; i <= 8; ++i)
		for (int j = 1; j <= 8; ++j)
		if (i != j)
		{
			int xx = x[i] - x[j];
			int yy = y[i] - y[j];
			dis[i][j] = sqrt(xx * xx + yy * yy);//勾股定理nb
		}
	dfs(1);
	printf("NO");
	return 0;
}

你可能感兴趣的:(dfs,数论,与,数学,dfs,数论)