NOIP2012开车旅行&疫情控制解题记录

首先是开车旅行

题目地址:

http://fzoj.xndxfz.com/JudgeOnline/problem.php?id=1349

题目大意:

这个我就不说了,看不懂的多读几遍题。(PS:其实我题意读错了3次,捂脸)

题解:

因为A和B是一人开一天,所以我们就可以将A与B各开一天看作一次开车。这样的话只要确定了起始位置,我们就可以通过倍增的方法快速找到总距离不超过X的所能到达的最远的点了。另外多说一句,这里如果是直接用n的时间查找最远点应该会超时,而如果用倍增可以将这里的n变为logn。
个人认为这道题比较坑的是预处理。也就是找距离当前城市第一近和第二近的城市。这个最开始我是想直接把全部点快排一遍,然后再找最近和第二近的城市,然后。。。我发现这个很难写,放弃了。这个时候,万能的Apache553给我介绍了一下set。我又看了一下Y_sofun的代码才A掉这道题。
下面就贴代码吧。

#include<set>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100005
using namespace std;
struct node
{
    int ord,high;
    friend bool operator<(node x,node y)
    {
        return x.high<y.high;
    }
}h[N];
struct node2
{
    int ord,val,high;
    friend bool operator<(node2 x,node2 y)
    {
        if(x.val==y.val)
        {
            return x.high<y.high;
        }
        return x.val<y.val;
    }
    node2 () {}
    node2(int a,int b,int c) : val(a),ord(b),high(c) {}
}t[10];
int n,fa[3][N],d[3][N],xaq,xbq,m,x0;
int grand[N][20],disa[N][20],disb[N][20];
set<node> S;
set<node>::iterator iter;
inline int read()
{
    int out=0,flagg=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') flagg=-1;
        ch=getchar();
    } 
    while(ch>='0'&&ch<='9')
    {
        out=out*10+ch-'0';
        ch=getchar();
    }
    return out*flagg;
}
void Init()
{
    memset(grand,0,sizeof(grand));
    memset(h,0,sizeof(0));
    memset(fa,0,sizeof(fa));
//  scanf("%d",&n);
    n=read();
    int cnt=0,i,j;
    for(i=1;i<=n;i++)
    {
//      scanf("%d",&h[i].high);
        h[i].high=read();
        h[i].ord=i;
    }
    for(i=n;i>=1;i--)
    {
        cnt=0;
        S.insert(h[i]);
        iter=S.find(h[i]);
        if(iter!=S.begin())
        {
            --iter;
            t[++cnt]=node2(abs((*iter).high-h[i].high),(*iter).ord,(*iter).high);
            if(iter!=S.begin())
            {
                --iter;
                t[++cnt]=node2(abs((*iter).high-h[i].high),(*iter).ord,(*iter
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值