zoukankan      html  css  js  c++  java
  • YYHS-怎样更有力气

    题目描述

    OI大师抖儿在夺得银牌之后,顺利保送pku。这一天,抖儿问长者:“我虽然已经保送了,但我的志向是为国家健康工作五十年。请问我应该怎样变得更有力气?”
      长者回答:“你啊,Too Young Too Simple,Sometimes Naive!如果你想要我教你,你要先进行艰苦的修行。”
    长者的住宅中有一堵长度为n的墙。每天抖儿起床修行,会选择一段长度为x的区间染成白色。长者的住宅附近有一群香港记者,为了借助抖儿拜访长者,第i天香港记者会将区间[li,ri]染成白色来讨好抖儿(也就是说,每天墙会被抖儿和香港记者各染一次)。现在抖儿已经预先知道了香港记者的动向,他想知道他最少几天就能把墙全部染白,完成修行。

    输入

    第一行三个整数n,m,x,分别表示墙的长度,天数和区间的长度。
    接下来m行,每行两个整数li、ri,表示香港记者在第i天会将区间[li,ri]染成白色。

    输出

    一行一个整数,表示抖儿最少几天能把墙全部染白。
    如果m天之后依然无法染白,则输出“Poor Douer!”

    样例输入

    10 3 3 2 5 4 8 9 10

    样例输出

    2

    提示

    【样例说明】

    第一天抖儿刷墙的区间为[1,3]

    第二天抖儿刷墙的区间为[8,10]

    【限制与约定】

    测试点编号

    n

    m

    x

    1

    n≤10

    m≤1

     

    2

    n≤10

    m≤10

    3

    n≤100

    m≤100

    4

    n≤1000

    m≤1000

    5

    n≤10000

    m≤10000

    6

    n≤100000

     

     

    m≤100000

     

    x=0

    7

    n≤1018

    8

    n≤100000

     

    9

    n≤1018

    10

    对于所有的数据,保证n≤1018,m≤100000,x≤n且数据随机

    【后记】

    在你的帮助下,抖儿完成修行的时间是原来的0.01倍。

    抖儿对长者说:“我明白了!只有每天坚持锻炼,才能获得力量。”

    长者嘿嘿一笑:“你想多了。我只是想让你刷墙而已。”

    说完,长者一溜烟地跑了,速度比香港记者还要快好几倍。
     

    题解

    这道题首先是二分需要的天数

    然后你需要统计出哪些区间没有被涂,然后用自己每天能涂的数量判断天数是否可以

    但是自己刚开始被如何统计剩余区间给卡住了,后来才知道可以把记者涂的区间从小到大排序(双关键字),然后就是判断剩余区间了

    当一段区间是4 5,后面一段是6 7的时候是没有区间漏涂的,所以判断q[i].l-q[i-1].r>1,但其实这样是不对的,自己就是被这个坑了

    比如

    3 7

    4 5

    7 8

    如果判断q[i].l-q[i-1].r>1,就会以为6~7这段区间是没有被涂得,但是其实前面3 7已经涂到7了,是没有剩余的,所以就要统计之前的max{q[i].r},判断q[i].l-Max>1

    统计完剩余区间后是计算自己涂的次数

    这里要多判断一下x=0的情况,还有要考虑到x很大的情况,说不定能够涂到两块区间的情况

    最后还要注意读入的n是10的18次,要long long读入

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define M 100005
     4 using namespace std;
     5 ll n,m,k,num,ss;
     6 int l,r,mid;
     7 ll x[M],y[M];
     8 bool Flag;
     9 struct node{ ll x,y; }b[M],a[M],q[M];
    10 bool cmp(node x,node y){ 
    11     if (x.x!=y.x) return x.x<y.x;
    12             else return x.y<y.y;
    13 }
    14 int main(){
    15     scanf("%lld%lld%lld",&n,&m,&k);
    16     for (int i=1;i<=m;i++)
    17         scanf("%lld%lld",&a[i].x,&a[i].y);
    18     l=1; r=m;
    19     while (l<=r){
    20         mid=(l+r)>>1;
    21         for (int i=1;i<=mid;i++) b[i]=a[i];
    22         sort(b+1,b+1+mid,cmp);
    23         int cnt=0;
    24         if (b[1].x>1) q[++cnt].x=1,q[cnt].y=b[1].x-1;
    25         ll Max=b[1].y;
    26         for (int i=2;i<=mid;i++){
    27             if (b[i].x-Max>1) q[++cnt].x=Max+1,q[cnt].y=b[i].x-1;
    28             if (b[i].y>Max) Max=b[i].y;
    29         }
    30         if (Max<n) q[++cnt].x=Max+1,q[cnt].y=n;
    31         bool flag=false;
    32         num=0; int p=1;
    33         ll last=0,s;
    34         if (!k){
    35             if (cnt>0) flag=true;
    36         } else
    37         while (p<=cnt){
    38             if (q[p].x<=last&&q[p].y>last) q[p].x=last+1; else
    39             if (q[p].y<=last){
    40                 p++; continue;
    41             }
    42             s=(q[p].y-q[p].x)/k+1;
    43             num=num+s;
    44             if (num>mid){
    45                 flag=true; break;
    46             }
    47             last=q[p].x+s*k-1;
    48             p++;
    49         }
    50         if (flag) l=mid+1; else{
    51             Flag=true;
    52             ss=mid;
    53             r=mid-1;
    54         }
    55     }
    56     if (!Flag) puts("Poor Douer!"); 
    57             else printf("%d
    ",ss);
    58     return 0;
    59 }
    View Code
  • 相关阅读:
    KMP算法中next数组的构建
    vijos 1243 生产产品
    codeforces 557E Ann and Half-Palindrome
    codeforces 557D Vitaly and Cycle
    vijos 1054 牛场围栏 【想法题】
    oracle数据库基本操作
    一位90后程序员的自述:如何从年薪3w到30w
    Oracle 树操作(select…start with…connect by…prior)
    oracle中的条件语句
    重置按钮_reset
  • 原文地址:https://www.cnblogs.com/zhuchenrui/p/7536845.html
Copyright © 2011-2022 走看看