• ZOJ3768 夹逼查找【STL__lower_bound()_的应用】


    首先学习一下lower_bound()

    函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置

    举例如下:

    一个数组number序列为:4,10,11,30,69,70,96,100.设要插入数字3,9,111.pos为要插入的位置的下标

    pos = lower_bound( number, number + 8, 3) - number,pos = 0.即number数组的下标为0的位置。

    pos = lower_bound( number, number + 8, 9) - number, pos = 1,即number数组的下标为1的位置(即10所在的位置)。

    pos = lower_bound( number, number + 8, 111) - number, pos = 8,即number数组的下标为8的位置(但下标上限为7,所以返回最后一个元素的下一个元素)。

    所以,要记住:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!~

    返回查找元素的第一个可安插位置,也就是“元素值>=查找值”的第一个元素的位置

    参考http://blog.csdn.net/niushuai666/article/details/6734403

    http://blog.csdn.net/ck_boss/article/details/23040385

    解题思路:

    看网上题解说至多会有3个可以拆分的因素...应该是可以证明的吧 =  =

    思路就是,先判断n是否可以由一个因素构成

    然后就是判断n是否可以有两个因素构成

    这里有点小技巧:

    1 int t2 = lower_bound( p , p + i + 1 , n - p[i] ) - p;//t2为另外一上限
    2 for(int j = t2 ; j && p[i] + p[j] * 2 >= n ; j-- )

    t2即为第二个因素的上限

    然后查找第三个元素的时候,就简单了

    只需要判断是否恰好满足条件即可

    if(p[i]+p[j]<n){  
        int temp=n-p[i]-p[j];  
        t=lower_bound(p,p+16000,temp)-p;  
        if(p[t]==temp){  
            flag3=true;  
            c=i,d=j,e=t;  
        }  

    完整AC代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 int p[16000];
     7 void init(){
     8     int sum=0;
     9     for(int i=1;i<16000;i++){
    10         sum += i;
    11         p[i]=sum;
    12     }
    13 }
    14 int main(){
    15     int numCase,n;
    16     scanf("%d",&numCase);
    17     init();
    18     while(numCase--){
    19         scanf("%d",&n);
    20         int t = lower_bound(p,p+16000,n)-p;//t为n在p数组中下标上限
    21         //printf("t = %d
    ",t);
    22         if(p[t] == n){
    23             printf("%d
    ",t);
    24             continue;
    25         }
    26         bool flag2=false,flag3=false;
    27         int a,b,c,d,e;
    28         for(int i = t ; i && p[i] * 2 >= n ; i--){//p[i] * 2 >= n为下限
    29             if(flag2) break;  
    30             int t2 = lower_bound(p,p+i+1,n-p[i]) - p;//t2为另外一上限
    31             for(int j=t2;j&&p[i]+p[j]*2>=n;j--){  
    32                 if(flag2) 
    33                     break;  
    34                 if(p[i]+p[j]==n){  
    35                     flag2=true;  
    36                     a=i,b=j; 
    37                     break;  
    38                 }  
    39                 else if(flag3)
    40                     continue;  
    41                 else if(p[i]+p[j]<n){  
    42                     int temp=n-p[i]-p[j];  
    43                     t=lower_bound(p,p+16000,temp)-p;  
    44                     if(p[t]==temp){  
    45                         flag3=true;  
    46                         c=i,d=j,e=t;  
    47                     }  
    48                 }  
    49             }  
    50         }  
    51         
    52         if(flag2) 
    53             printf("%d %d
    ",a,b);
    54         else 
    55             printf("%d %d %d
    ",c,d,e);
    56     }
    57     return 0;
    58 }
    Continuous Login

    Time Limit: 2 Seconds      Memory Limit: 131072 KB      Special Judge

    Pierre is recently obsessed with an online game. To encourage users to log in, this game will give users a continuous login reward. The mechanism of continuous login reward is as follows: If you have not logged in on a certain day, the reward of that day is 0, otherwise the reward is the previous day's plus 1.

    On the other hand, Pierre is very fond of the number N. He wants to get exactly N points reward with the least possible interruption of continuous login.

    Input

    There are multiple test cases. The first line of input is an integer T indicates the number of test cases. For each test case:

    There is one integer N (1 <= N <= 123456789).

    Output

    For each test case, output the days of continuous login, separated by a space.

    This problem is special judged so any correct answer will be accepted.

    Sample Input

    4
    20
    19
    6
    9
    

    Sample Output

    4 4
    3 4 2
    3
    2 3
    

    Hint

    20 = (1 + 2 + 3 + 4) + (1 + 2 + 3 + 4)

    19 = (1 + 2 + 3) + (1 + 2 + 3 + 4) + (1 + 2)

    6 = (1 + 2 + 3)

    9 = (1 + 2) + (1 + 2 + 3)

    Some problem has a simple, fast and correct solution.

  • 相关阅读:
    BZOJ 5308 [ZJOI2018] Day2T2 胖 | 二分 ST表
    CodeForces 464E The Classic Problem | 呆克斯歘 主席树维护高精度
    BZOJ5298 [CQOI2018] 交错序列 | 矩阵乘法和一个trick
    # BZOJ5300 [CQOI2018]九连环 题解 | 高精度 FFT
    [BZOJ5248] 2018九省联考 D1T1 一双木棋 | 博弈论 状压DP
    【2018九省联考】后的瞎扯
    BZOJ 4671 异或图 | 线性基 容斥 DFS
    Luogu 4294 [WC2008]游览计划 | 斯坦纳树
    BZOJ 2434 阿狸的打字机 | AC自动机
    UOJ#7. 【NOI2014】购票 | 线段树 凸包优化DP
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/3649806.html
Copyright © 2020-2023  润新知