zoukankan      html  css  js  c++  java
  • 洛谷P3407 散步[分组]

    题目描述

    一条道路上,位置点用整数A表示。

    当A=0时,有一个王宫。当A>0,就是离王宫的东边有A米,当A<0,就是离王宫的西边有A米。

    道路上,有N个住宅从西向东用1-N来标号。每个住宅有一个人。住宅只会存在于偶数整数点。

    该国国王认为,国民体质下降,必须要多运动,于是下命令所有人都必须出门散步。所有的国民,一秒钟可以走1米。每个国民各自向东或者向西走。这些方向你是知道的。命令发出后所有人同时离开家门开始散步。

    然而该国的国民个都很健谈,如果在散步途中两个人相遇,就会停下来交谈。正在走路的人碰到已经停下来的人(重合)也会停下来交谈。一但停下来,就会聊到天昏地暗,忘记了散步。

    现在命令已经发出了T秒,该国有Q个重要人物,国王希望能够把握他们的位置。你能帮他解答吗?

    输入输出格式

    输入格式:

    第一行是3个整数,N,T,Q

    接下来N行,每行两个整数Ai,Ri。Ai是家的坐标,如果Ri是1,那么会向东走,如果是2,向西。数据保证Ai是升序排序,而且不会有两个人初始位置重合。

    接下来Q行,每行一个整数,表示国王关心的重要人物。

    输出格式:

    Q行,每行一个整数,表示这个人的坐标。

    输入输出样例

    输入样例#1:
    6 6 4
    -10 1
    -6 2
    -4 1
    2 1
    6 2
    18 2
    2
    3
    4
    6
    输出样例#1:
    -8
    2
    4
    12

    说明

    20%数据 N<=100,T<=10000

    另外20%数据 N<=5000

    另外20%数据 从最西边数起连续的若干国民全部往东,剩下的全部往西

    100%数据 Ai为偶数,|Ai|<=10^18,|T|<=10^18,1<=Q<=N<=100000.


    只想到部分分

    官方题解:

    为什么数据范围这么奇怪?因为这个范围已经剧透了。

    我们先考虑“从西边数连续的人全部往东,剩下的全部往西”这个。

    我们会发现,他们最后都会集中在一个点上。哪个点?就是中间的那对面对面的中间点。我们只要判断时间内,人能不能走到这个点停下来。于是20分get。

    100分呢?我们是不是可以吧所有人分成若干组,然后每一组分别计算啊?

    例如样例,我们将(认为往东,)往西。他们最终会停在|的地方。

      第一组                   第二组
    (    |    )          (  (     |     )  )
    -10  -8   -6         -4 2     4     6 18

    于是我们就很清楚了。

    那最左边的人向左,最右边的人向右怎么办呢?那就让他走呗,特判一下,反正永远也停不下来。

    想到那20%了,原来扫描然后分组就可以了......................

    //
    //  main.cpp
    //  luogu10r2.2
    //
    //  Created by Candy on 10/15/16.
    //  Copyright © 2016 Candy. All rights reserved.
    //
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int N=1e5+5;
    inline ll read(){
        char c=getchar();ll x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    ll n,t,Q,a[N],d[N],q[N],ans[N];
    void cal(int l,int r){
        if(l==r) a[l]+=d[l]*t;
        else if(d[l]==-1||d[r]==1)
            for(int i=l;i<=r;i++) a[i]+=d[i]*t;
        else{
            int pos=l;
            while(d[pos+1]==1) pos++;
            ll mid=(a[pos]+a[pos+1])/2;
            for(int i=l;i<=r;i++){
                ll tmp=a[i]+t*d[i];
                if((a[i]<=mid&&tmp>=mid)||(a[i]>=mid&&tmp<=mid)) a[i]=mid;
                else a[i]=tmp;
            }
        }
    }
    int main(int argc, const char * argv[]) {
        n=read();t=read();Q=read();
        for(int i=1;i<=n;i++) {
            a[i]=read(),d[i]=read();
            if(d[i]==2) d[i]=-1;
        }
        for(int i=1;i<=Q;i++) q[i]=read();
        
        int l=1,dir=1;
        for(int i=1;i<=n;i++){
            if(d[i]==1&&dir==-1){
                cal(l,i-1);
                l=i;
                dir=1;
            }
            dir=d[i];
        }
        if(l<=n) cal(l,n);
        for(int i=1;i<=Q;i++) printf("%lld
    ",a[q[i]]);
        return 0;
    }
  • 相关阅读:
    Oracle Core 学习笔记二 Transactions 和 Consistency 说明
    Oracle AUTO_SPACE_ADVISOR_JOB 说明
    Windows 下 ftp 上传文件 脚本
    Oracle 11g 中 Direct path reads 特性 说明
    Linux 使用 wget 下载 Oracle 软件说明
    Oracle 10g read by other session 等待 说明
    Oracle 11g RAC INS06006 Passwordless SSH connectivity not set up between the following node(s) 解决方法
    SecureCRT 工具 上传下载数据 与 ASCII、Xmodem、Ymodem 、Zmodem 说明
    Oracle RAC root.sh 报错 Timed out waiting for the CRS stack to start 解决方法
    Oracle RESETLOGS 和 NORESETLOGS 区别说明
  • 原文地址:https://www.cnblogs.com/candy99/p/5967339.html
Copyright © 2011-2022 走看看