题解 P1442 【铁球落地】

· · 题解

建图跑Dijkstra

此题卡我半天...我太菜了...o(╥﹏╥)o

大家可以看看评测记录,有一页多都是我...

本来以为TLE是哪里出了点小问题,然后调了半天,又是不用vector又是玄学优化的...最后看了题解才发现是建图太慢了...

此分界线以上是废话...

思路

代码

#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<cctype>
#include<cstring>
#define rint register int
inline int read()
{
    rint k=0,c=getchar();
    while(!isdigit(c))
        c=getchar();
    while(isdigit(c))
    {
        k=10*k+c-'0';
        c=getchar();
    }
    return k;
}
struct Q{
    int h,x,y;
    Q(){}
    Q(int _h,int _x,int _y):h(_h),x(_x),y(_y){}
}a[100005];
struct P{
    int x,d;
    P(){}
    P(int _x,int _d):x(_x),d(_d){}
}v[200005][2];
const bool operator <(P a,P b)
{
    return a.d>b.d;
}
inline bool cmp(Q a,Q b)
{
    return a.h<b.h;
}
std::priority_queue<P> que;
int vis[200005],n,max,x,y;
int main()
{
    std::memset(v,-1,sizeof(v));//init
    n=read();
    max=read();
    x=read();
    y=read();
    for(rint i=1;i<=n;++i)
    {
        a[i].h=read();
        a[i].x=read();
        a[i].y=read();
        if(a[i].h>y)//delete
        {
            --n;
            --i;
        }
    }
    std::sort(a+1,a+n+1,cmp);
    a[++n]=Q(y,x,x);
    std::queue<int> tq;
    tq.push(n); 
    while(!tq.empty())
    {
        int i=tq.front();
        tq.pop();
        //find left
        int mem=0,point=a[i].x,h=a[i].h;
        for(int j=i-1;j>=1&&h-max<=a[j].h;--j)
            if(a[j].x<=point&&a[j].y>=point)
            {
                mem=j;
                break;
            }
        int delta=h-a[mem].h;
        if(delta<=max)
        {
            if(mem==0)
                v[i][0]=P(0,0);
            else
            {
                v[i][1]=P(n+mem,a[mem].y-point),v[i][0]=P(mem,point-a[mem].x);
                if(!vis[mem])
                {
                    tq.push(mem); 
                    vis[mem]=1;
                }
            }
        }
        //find right
        mem=0,point=a[i].y;
        for(int j=i-1;j>=1&&h-max<=a[j].h;--j)
            if(a[j].x<=point&&a[j].y>=point)
            {
                mem=j;
                break;
            }
        delta=h-a[mem].h;
        if(delta<=max)
        {
            if(mem==0)
                v[n+i][0]=P(0,0);
            else
            {
                v[n+i][1]=P(n+mem,a[mem].y-point),v[n+i][0]=P(mem,point-a[mem].x);
                if(!vis[mem])
                {
                    tq.push(mem); 
                    vis[mem]=1;
                }
            }
        }
    }
    std::memset(vis,0,sizeof(vis));
    que.push(P(n,0));
    rint now,d;
    while(!que.empty())//Dijkstra
    {
        now=que.top().x;
        d=que.top().d;
        que.pop();
        if(now==0)
        {
            printf("%d",d+y);
            return 0;
        }
        if(vis[now])
            continue;
        vis[now]=1;
        for(rint i=0;i<=1;++i)
            if(v[now][i].x!=-1&&!vis[v[now][i].x])
                que.push(P(v[now][i].x,v[now][i].d+d));
    }
    return 0;
} 

评测结果:130ms/5.63MB

目前RANK1,还算可以了(等那些优化神佬一来就下去了...)