挑战
题目链接:https://www.luogu.com.cn/problem/P1686
题解:
将起始点作为原点
(
0
,
0
)
(0,0)
(0,0),每次移动后,坐标记为
(
x
i
,
y
i
)
(x_i,y_i)
(xi,yi)。共n+1个点,因为捷径是直线,所以每个点只需要找到x相等或y相等的点。
暂时只考虑x相等的状态,设当前共有k个点的x相等,y分别为
y
1
,
y
2
,
.
.
.
,
y
k
y_1,y_2,...,y_k
y1,y2,...,yk。将y顺序排列,捷径一定是
y
1
−
>
y
2
y_1->y_2
y1−>y2,
y
2
−
>
y
3
y_2->y3
y2−>y3,…,
y
k
−
1
−
>
y
k
y_{k-1}->y_k
yk−1−>yk。长度就为其坐标差。
y相等时同理。所有的状态求最小值即为所求。
注意有些原本的路径就是走的捷径,这些需要忽略。且题目要求输出 捷径最短,开始编号最小,结束编号最小的,所以在计算时,不仅需要记录坐标,还要记录处于该点的时间。
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define eps 1e-6
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 400100;
const int mod = 10000007;
struct node{
int pos, id;
node(){}
node(int a, int b):pos(a), id(b){}
};
char str[maxn];
int na[maxn], nb[maxn], a[maxn], b[maxn];
vector<node> g[4][maxn];
bool cmp(node a, node b);
int main()
{
int n, i, j, k, pa, pb, num1, num2, mx, l, r;
char ch;
scanf("%d %s", &n, str+1);
num1 = num2 = 0;
g[0][0].push_back(node(0, 0));
g[2][0].push_back(node(0, 0));
for(i=1;i<=n;i++){
if(str[i] == 'W')num1++;
else if(str[i] == 'E')num1--;
if(str[i] == 'N')num2++;
else if(str[i] == 'S') num2--;
a[i] = num1;
b[i] = num2;
if(num1>=0)g[0][num1].push_back(node(b[i], i));
else g[1][-num1].push_back(node(b[i], i));
if(num2>=0)g[2][num2].push_back(node(a[i], i));
else g[3][-num2].push_back(node(a[i], i));
}
for(i=0;i<4;i++)
for(j=0;j<=n;j++)
sort(g[i][j].begin(), g[i][j].end(), cmp);
mx = INF;
for(i=0;i<4;i++)
for(j=0;j<n;j++)
for(k=1;k<g[i][j].size();k++){
int dis = abs(g[i][j][k].pos-g[i][j][k-1].pos);
int al = min(g[i][j][k].id, g[i][j][k-1].id);
int ar = max(g[i][j][k].id, g[i][j][k-1].id);
if(dis == ar - al)
continue;
if(dis < mx || dis == mx && al<l || dis == mx && al == l && ar > r){
mx = dis;
l = al;
r = ar;
if(a[l] == a[r]){
if(b[l] < b[r])ch = 'N';
else ch = 'S';
}else if(b[l] == b[r]){
if(a[l] < a[r])ch = 'W';
else ch = 'E';
}
}
}
printf("%d %d %d %c\n", mx, l, r, ch);
return 0;
}
bool cmp(node a, node b)
{
return a.pos < b.pos;
}