07-图5 Saving James Bond - Hard Version

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

typedef struct {
	int x, y;
	int pre;
	int escape;
} Vertex;

typedef struct Node {
	int value;
	struct Node *next;
} Table;

int Abs(int a) //求a的绝对值
{
	if (a < 0)
		a = -a;
	return a;
}

int inLake(int x, int y) {		//判断鳄鱼是否在湖里面;在岛上或岸上的鳄鱼不与任何节点相连
	if (15 * 15 >= 4 * (x * x + y * y))
		return 0;
	if (Abs(x) >= 50 || Abs(y) >= 50)
		return 0;
	return 1;
}

void Create_Graph(Table *table, Vertex *v, int N, int D);
int BFS(Table *table, Vertex *vertex, int N, int D);
void Destroy_Graph(Table *table, int N);

int main(int argc, char const *argv[])
{
	// freopen("test.txt", "r", stdin);
	int N, D;
	scanf("%d %d", &N, &D);
	if (2 * D + 15 > 100) {
		printf("1\n");
		return 0;
	}
	Vertex vertex[101];
	vertex[0].x = vertex[0].y = 0, vertex[0].escape = 0, vertex[0].pre = -1;//初始化小岛结点
	for (int i = 1; i <= N; i++) {	//下标从1开始,小岛对应0
		scanf("%d %d", &vertex[i].x, &vertex[i].y);
		vertex[i].pre = -1;
		if (Abs(vertex[i].x) + D >= 50 || Abs(vertex[i].y) + D >= 50)
			vertex[i].escape = 1;
		else
			vertex[i].escape = 0;
	}
	Table table[101] = {}; 			//将所有指针初始化为NULL,值初始化为0
	Create_Graph(table, vertex, N, D);
	int escape = BFS(table, vertex, N, D);//BFS求最短路径,返回逃跑成功的最后一个节点,不能逃跑返回0
	if (escape != 0) {
		int pace = 0;
		int stack[100] = {}, top = 0;
		int v = escape;
		while (v != -1) {
			pace++;
			stack[top++] = v;
			v = vertex[v].pre;
		}
		printf("%d\n", pace);
		while (top) {
			v = stack[--top];
			if (v != 0)
				printf("%d %d\n", vertex[v].x, vertex[v].y);
		}
	}
	else
		printf("0\n");
	Destroy_Graph(table, N);
	return 0;
}

void Destroy_Graph(Table *table, int N)
{
	for (int i = 0; i <= N; i++) {
		Table *p = table[i].next;
		while (p) {
			Table *tmp = p;
			p = p->next;
			free(tmp);
		}
	}
}

void Create_Graph(Table *table, Vertex *v, int N, int D)
{
	Table *pre = &table[0]; 		//pre始终指向插入结点的前一个
	for (int i = 1; i <= N; i++) { 	//将第一跳的结点接到table[0]后,并升序排序
		if (inLake(v[i].x, v[i].y) && (v[i].x * v[i].x + v[i].y * v[i].y) * 4 <= (2 * D + 15)*(2 * D + 15)) {
			Table *tmp = (Table*)malloc(sizeof(Table));//一开始后一个Table打成了table,结果free时一直内存溢出,查了好久才看到_(:з」∠)_
			tmp->value = i;
			pre = &table[0];		//pre始终指向插入结点的前一个
			while (pre->next && (v[i].x*v[i].x + v[i].y*v[i].y) > (v[pre->next->value].x*v[pre->next->value].x + v[pre->next->value].y*v[pre->next->value].y))
				pre = pre->next;
			tmp->next = pre->next; 	//将tmp插入到pre后
			pre->next = tmp;
		}
	}
	for (int i = 1; i <= N; i++) {	//将鳄鱼的节点连成网络
		if (!inLake(v[i].x, v[i].y))
			continue;
		for (int j = 1; j <= N; j++) {
			if (j != i && ((v[i].x - v[j].x)*(v[i].x - v[j].x) + (v[i].y - v[j].y)*(v[i].y - v[j].y)) <= D*D) {
				Table *tmp = (Table*)malloc(sizeof(Table));
				tmp->value = j;
				tmp->next = table[i].next;
				table[i].next = tmp;
			}
		}
	}
}

int BFS(Table *table, Vertex *vertex, int N, int D)
{
	int v = table[0].value;			//起始节点
	int queue[101] = {}, head = 0, rear = 0;		//队列
	int visited[101] = {};			//用于标记节点是否已访问
	visited[v] = 1;
	queue[rear++] = v;				//第一个节点入队
	while (rear - head) {
		v = queue[head++];
		if (vertex[v].escape)		//如果当前节点能跳到岸上,返回当前结点
			return v;
		Table *tmp = &table[v];		//否则,将该节点所有没有被访问的邻节点都入队
		while (tmp = tmp->next) {	//遍历每个邻接点
			int u = tmp->value;
			if (visited[u] == 0) {	//如果该邻节点没有被访问,入队
				visited[u] = 1;
				queue[rear++] = u;
				vertex[u].pre = v;	//记录当前入队节点的前一个节点
			}
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值