P1686 挑战

coder2023 / 2024-03-01 / 原文

题目大意
给定n个点,每个点大致包含如下信息:

  • 节点编号
  • 横纵坐标
    求两个编号不相邻的点是否有最短路径即所谓捷径,而两点必须在同一直线上,即两点必处于同行或同列
    理解题意后,不难想到可以有如下做法:
    将所有节点信息储存下来,分成同行一类,同列一类,模拟题意即可
#include <algorithm>
#include <iostream>
#include <string>
#include <climits>
#include <cstdio>
#include <cmath>
using namespace std; 
struct node
{
	int number;
	int x;
	int y;	
};
bool cmpx(node parameter1,node parameter2)
{
	return parameter1.x < parameter2.x || (parameter1.x == parameter2.x && parameter1.y < parameter2.y);
}
bool cmpy(node parameter1,node parameter2)
{
	return parameter1.y < parameter2.y || (parameter1.y == parameter2.y && parameter1.x < parameter2.x);
}
int n;
const int maxn = 2.5E5 + 5; 
string str;
node arr[maxn];
int length = INT_MAX,from = INT_MAX,to = INT_MIN;
char dir;
void solve1()
{
	char tem_dir;
	int local1,local2;
	sort(arr,arr+n+1,cmpx);
	for(int i = 0; i < n; i++)
	{
		if(arr[i].x == arr[i+1].x)
		{
			if(abs(arr[i].number - arr[i+1].number) == 1)continue;
			int tem_length = abs(arr[i].y - arr[i+1].y);
			if(arr[i].number < arr[i+1].number)local1 = i,local2 = i+1;
			else local1 = i+1,local2 = i;
			if(arr[local1].y < arr[local2].y)tem_dir = 'N';
			else tem_dir = 'S';
			if(tem_length == length)
			{
				if(arr[local1].number < from)from = arr[local1].number,to = arr[local2].number,length = tem_length,dir = tem_dir;
				else 
				{
					if(arr[local1].number == from && arr[local2].number > to)
					{
						from = arr[local1].number,to = arr[local2].number,length = tem_length,dir = tem_dir;
					} 
				}
			}
			if(length > tem_length)
			{
				from = arr[local1].number,to = arr[local2].number,length = tem_length,dir = tem_dir;
			}
		}
	}
}
void solve2()
{
	char tem_dir;
	int local1,local2;
	sort(arr,arr+n+1,cmpy);
	for(int i = 0; i < n; i++)
	{
		if(arr[i].y == arr[i+1].y)
		{
			if(abs(arr[i].number - arr[i+1].number) == 1)continue;
			int tem_length = abs(arr[i].x - arr[i+1].x);
			if(arr[i].number < arr[i+1].number)local1 = i,local2 = i+1;
			else local1 = i+1,local2 = i;
			if(arr[local1].x < arr[local2].x)tem_dir = 'E';
			else tem_dir = 'W';
			if(tem_length == length)
			{
				if(arr[local1].number < from)from = arr[local1].number,to = arr[local2].number,length = tem_length,dir = tem_dir;
				else 
				{
					if(arr[local1].number == from && arr[local2].number > to)
					{
						from = arr[local1].number,to = arr[local2].number,length = tem_length,dir = tem_dir;
					} 
				}
			}
			if(length > tem_length)
			{
				from = arr[local1].number,to = arr[local2].number,length = tem_length,dir = tem_dir;
			}
		}
	}
}
int main() 
{
	scanf("%d",&n);
	arr[0].number = 0;
	arr[0].x = arr[0].y = 2.5E5+5;
	int lastx;
	int lasty;
	lastx = lasty = 2.5E5+5;
	cin >> str;
	for(int i = 0; i < n; i++)
	{
		if(str[i] == 'N')lasty++;
		else if(str[i] == 'S')lasty--;
		else if(str[i] == 'W')lastx--;
		else if(str[i] == 'E')lastx++;
		arr[i + 1].x = lastx;
		arr[i + 1].y = lasty;
		arr[i + 1].number = i + 1;
	} 
	solve1();
	solve2();
	printf("%d %d %d %c\n",length,from,to,dir);
	return 0;
}