洛谷_1686 挑战(贪心)

挑战

题目链接: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 yk1>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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值