zoukankan      html  css  js  c++  java
  • 2017.10.4北京清北综合强化班DAY4

    财富(treasure)

    Time Limit:1000ms   Memory Limit:128MB

     

    题目描述

    LYK有n个小伙伴。每个小伙伴有一个身高hi。

    这个游戏是这样的,LYK生活的环境是以身高为美的环境,因此在这里的每个人都羡慕比自己身高高的人,而每个人都有一个属性ai表示它对身高的羡慕值。

    这n个小伙伴站成一列,我们用hi来表示它的身高,用ai来表示它的财富。

    每个人向它的两边望去,在左边找到一个最近的比自己高的人,然后将ai朵玫瑰给那个人,在右边也找到一个最近的比自己高的人,再将ai朵玫瑰给那个人。当然如果没有比自己身高高的人就不需要赠送别人玫瑰了。也就是说一个人会给0,1,2个人玫瑰(这取决于两边是否有比自己高的人)。

    每个人都会得到若干朵玫瑰(可能是0朵),LYK想知道得了最多的玫瑰的那个人得了多少玫瑰。(然后嫁给他>3<)

     

    输入格式(treasure.in)

        第一行一个数n表示有n个人。

        接下来n行,每行两个数hi,ai。

     

    输出格式(treasure.out)

        一个数表示答案。

     

    输入样例

    3

    4 7

    3 5

    6 10

     

    输出样例

    12

     

    样例解释

    第一个人会收到5朵玫瑰,第二个没人送他玫瑰,第三个人会收到12朵玫瑰。

     

    数据范围

    对于50%的数据n<=1000,hi<=1000000000。

    对于另外20%的数据n<=50000,hi<=10。

    对于100%的数据1<=n<=50000,1<=hi<=1000000000。1<=ai<=10000。

    题解:预处理每个数左右第一个比他大的数 O(n)更新的答案

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define inf 2100000000
    using namespace std;
    
    int n,ret;
    int l[50009],r[50009],ans[50009];
    struct Per{
        int h,v;
    }per[50009];
    
    inline int read(){
        char ch=getchar();int x=0,f=1;
        for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
    
    int main(){
        n=read();
        for(int i=1;i<=n;i++){
            per[i].h=read();per[i].v=read();
            l[i]=r[i]=i;
        }    
        per[n+1].h=per[0].h=inf;
        for(int i=1;i<=n;i++){
            int h=per[i].h;
            while(h>=per[l[i]-1].h)l[i]=l[i]-1;
            while(h>=per[r[i]+1].h)r[i]=r[i]+1;
        }
        for(int i=1;i<=n;i++){
            l[i]--;r[i]++;
            if(l[i]!=0)ans[l[i]]+=per[i].v;
            ret=max(ret,ans[l[i]]);
            if(r[i]<=n)ans[r[i]]+=per[i].v;
            ret=max(ret,ans[r[i]]); 
        } 
        printf("%d
    ",ret);
        return 0;
    }
    /*
    9
    9 15
    9 9
    19 15
    11 3
    2 15
    15 10
    10 3
    15 17
    20 1
    */
    AC

    考场看到这个题目 左边第一个比它大的..不是单调栈么..以前做过这样的题目

    然后背上code,结果WA了,之前有地方没搞懂..放过了..orz..活该emmm...

    正方形(square)

    Time Limit:1000ms   Memory Limit:128MB

     

    题目描述

    在一个10000*10000的二维平面上,有n颗糖果。

    LYK喜欢吃糖果!并且它给自己立了规定,一定要吃其中的至少C颗糖果!

    事与愿违,LYK只被允许圈出一个正方形,它只能吃在正方形里面的糖果。并且它需要支付正方形边长的价钱。

    LYK为了满足自己的求食欲,它不得不花钱来圈一个正方形,但它想花的钱尽可能少,你能帮帮它吗?

     

    输入格式(square.in)

        第一行两个数C和n。

        接下来n行,每行两个数xi,yi表示糖果的坐标。

     

    输出格式(square.out)

        一个数表示答案。

     

    输入样例

    3 4

    1 2

    2 1

    4 1

    5 2

     

    输出样例

    4

     

    样例解释

    选择左上角在(1,1),右下角在(4,4)的正方形,边长为4。

     

    数据范围

    对于30%的数据n<=10。

    对于50%的数据n<=50。

    对于80%的数据n<=300。

    对于100%的数据n<=1000。1<=xi,yi<=10000。

    题目大意:用边长最小的正方形,把在10000*10000矩形上的n个糖果至少套住c个

    题解:二分答案

    二分正方形的边长,再check

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define maxn 1009
    using namespace std;
    
    int c,n,l,r,ans,mid,b[maxn];
    struct node{
        int x,y;
    }a[maxn];
    bool cmp(node a,node b){
        return a.x<b.x;
    }
    bool work(int l,int r){
        if(r-l+1<c)return false;
        int o=0;
        for(int i=l;i<=r;i++)b[++o]=a[i].y;
        sort(b+1,b+o+1);
        for(int i=c;i<=o;i++)
         if(b[i]-b[i-c+1]<=mid)return true;
         return false;
    }
    
    bool check(int p){
        int xx=1;
        for(int i=1;i<=n;i++){
            if(a[i].x-a[xx].x>p){
                if(work(xx,i-1))return true;
                while(a[i].x-a[xx].x>p)xx++;
            }
        }
        if(work(xx,n))return true;
        return false;
    }
    
    int main(){
        scanf("%d%d",&c,&n);
        for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
        sort(a+1,a+n+1,cmp);l=1;r=10000;
        while(l<=r){
            mid=(l+r)>>1;
            if(check(mid)){
                ans=mid+1;r=mid-1;
            }else l=mid+1;
        }
        cout<<ans<<endl;
        return 0;
    }
    AC

    追逐(chase)

     

    Time Limit:1000ms   Memory Limit:128MB3

     

    题目描述

    这次,LYK以一个上帝视角在看豹子赛跑。

    在一条无线长的跑道上,有n只豹子站在原点。第i只豹子将在第ti个时刻开始奔跑,它的速度是vi/时刻。

    因此在不同的时刻,这n只豹子可能在不同的位置,并且它们两两之间的距离也将发生变化。

    LYK觉得眼光八方太累了,因此它想找这么一个时刻,使得最远的两只豹子的距离尽可能近,当然这不能是第0时刻或者第0.01时刻。它想知道的是最迟出发的豹子出发的那一刻开始,离得最远的两只豹子在距离最小的时候这个距离是多少。

    当然这个时刻不仅仅可能发生在整数时刻,也就是说可能在1.2345时刻这个距离最小。

     

    输入格式(chase.in)

        第一行一个数n。

        接下来n行,每行两个数分别是ti和vi。

     

    输出格式(chase.out)

        输出一个数表示答案,你只需保留小数点后两位有效数字就可以了。

     

    输入样例

    3

    1 4

    2 5

    3 7

     

    输出样例

    0.33

     

    样例解释

    在第5+2/3这个时刻,第一只豹子在18+2/3这个位置,第二只豹子在18+1/3这个位置,第三只豹子在18+2/3这个位置,最远的两只豹子相距1/3的距离,因此答案是0.33。

     

    数据范围

    对于20%的数据n=2。

    对于20%的数据n=3

    对于60%的数据n<=100。

    对于80%的数据n<=1000。

    对于100%的数据n<=100000,1<=vi,ti<=100000。

    题解:计算几何 弃疗

    把每个豹子看成一条直线。

    把距离起点最远的和最近的标记出来,那么答案就是所有绿色条条最小的那一个。

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    const long double INF=(long double)1000000000*10;
    long double L,R,mid,ans,hh[100005];
    int r,rr,i,n,MAX,X,Y,cnt,vv[100005],vv2[100005];
    struct node2 {int t; long double l;} s[200005],S[200005];
    struct node {int t,v;} t[100005];
    int cmp(node i,node j) {return i.v<j.v || i.v==j.v && i.t>j.t;}
    struct Node {long double x;int y,z;} p[200005];
    int CMP(Node i,Node j) {return i.x<j.x;}
    long double work(int x,long double y) {return (long double)t[x].v*y-hh[x];}
    int main()
    {
        freopen("chase.in","r",stdin);
        freopen("chase.out","w",stdout);
        while (1)
        {
            scanf("%d",&n);
           // if (n==0) return 0;
            MAX=0;
            for (i=1; i<=n; i++)
            {
                scanf("%d%d",&t[i].t,&t[i].v);
                MAX=max(MAX,t[i].t);
            }
            sort(t+1,t+n+1,cmp); int MIN=t[n].t;
            for (i=n-1; i>=2; i--)
            {
                if (t[i].t>MIN) vv[i]=1; else
                MIN=t[i].t,vv[i]=0;
            }
            for (i=1; i<=n; i++) hh[i]=(long double)t[i].t*t[i].v;
            r=1; s[1].l=MAX; s[1].t=1; s[2].l=INF; vv[n]=0;
            for (i=2; i<=n; i++)
            if (!vv[i])
            {
                while (r && work(i,s[r].l)>=work(s[r].t,s[r].l)) r--;
                if (!r) {r=1; s[1].l=MAX; s[1].t=i; continue;}
                L=s[r].l; R=s[r+1].l; mid=(L+R)/2.0;
                for (int I=1; I<=80; I++)
                {
                    if (work(i,mid)>=work(s[r].t,mid)) {R=mid; mid=(L+R)/2.0;} else {L=mid; mid=(L+R)/2.0;}
                }
                s[++r].l=mid; s[r].t=i; s[r+1].l=INF;
            }
            rr=1; S[1].l=MAX; S[2].l=INF; S[1].t=n;
            MIN=t[1].t;
            for (i=2; i<n; i++)
              if (t[i].t<MIN) vv2[i]=1; else
                MIN=t[i].t,vv2[i]=0;
            for (i=n-1; i>=1; i--)
            if (!vv2[i])
            {
                while (rr && work(i,S[rr].l)<=work(S[rr].t,S[rr].l)) rr--;
                if (!rr) {rr=1; S[1].l=MAX; S[1].t=i; continue;}
                L=S[rr].l; R=S[rr+1].l; mid=(L+R)/2.0;
                for (int I=1; I<=80; I++)
                {
                    if (work(i,mid)<=work(S[rr].t,mid)) {R=mid; mid=(L+R)/2.0;} else {L=mid; mid=(L+R)/2.0;}
                }
                S[++rr].l=mid; S[rr].t=i; S[rr+1].l=INF;
            }
            cnt=0;
            for (i=1; i<=r; i++) {p[++cnt].x=s[i].l; p[cnt].y=1; p[cnt].z=s[i].t;}
            for (i=1; i<=rr; i++) {p[++cnt].x=S[i].l; p[cnt].y=0; p[cnt].z=S[i].t;}
            sort(p+1,p+cnt+1,CMP); X=Y=0; ans=INF;
            for (i=1; i<=cnt; i++)
            {
                if (p[i].y==1) X=p[i].z; else Y=p[i].z;
              //  printf("%.5f
    ",(double)p[i].x);
                if (X && Y) ans=min(ans,work(X,p[i].x)-work(Y,p[i].x));
            }
            printf("%.2f
    ",fabs((double)ans));
            return 0;
        }
    }
    AC
  • 相关阅读:
    后缀数组板子
    上海高校金马五校赛 J
    西安电子科技大学第16届程序设计竞赛网络同步赛 G-小国的复仇
    HDU
    string 与char* char[]之间的转换 .
    (分治思想)(归并排序)C
    如何取出 Map中key和value的值
    C++ STL 中 map 容器的说明和使用技巧 .
    (经典map)A
    Babelfish(6.1.2)(sort结构体排序)(sscanf()基本使用方法)(二分法)
  • 原文地址:https://www.cnblogs.com/zzyh/p/7627122.html
Copyright © 2011-2022 走看看