• Codeforces Round #948 (Div. 2) C


    题目链接:http://codeforces.com/contest/948/problem/C

    题意:小花很喜欢雪  就像每一个没有来过东北的孩子一样  给出n天的状态 包括每天收集到雪的体积与该天的温度 问每天会融化多少体积的雪  每一天收集到的雪自成一堆  温度为x则每一堆雪融化x体积  如果剩余不到x体积 就全部融化完

    思路:这道题很容易想到是解法就是n^2的跑 这个题的n可以达到1e5 n^2的跑会超时  想到一个优化就是开两个queue 不停地把还剩下雪的体积存起来  省去了检索体积为零的时间  但是在第11组的时候还是超时 

    题解:输入过程不用说了  我的想法是对每天的温度遍历一遍  正解是对每天的雪量遍历一遍  每天的雪使用二分查找找到这个雪在那一天会被用完 二分查找比扫一遍省很多时间  然后把这个范围内每天的ans加上对应的温度 最后一天加温度还是剩余的雪量需要特殊考虑 这样的话需要预处理出来温度的前缀和  用在二分查找里面 基本上是nlog的复杂度 但是感觉比上面那个想法省不了多少时间啊 上面那个也是每天的ans直接更新 更新的次数也是有多少雪对这一天有贡献就加上 不知道什么区别 先试试

    原始想法 第十一组超时

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    #include<queue>
    
    using namespace std;
    
    long long n;
    long long v[100010];
    long long t;
    long long ans;
    long long num;
    long long f;
    
    void read(long long &x){
        x=0;char c=getchar();
        while(c<'0' || c>'9')c=getchar();
        while(c>='0' && c<='9'){
            x=x*10+c-'0';
            c=getchar();
        }
    }
    
    void write(long long x){
        if(x==0){putchar(48);return;}
        int len=0,dg[20];
        while(x>0){dg[++len]=x%10;x/=10;}
        for(int i=len;i>=1;i--)putchar(dg[i]+48);
    }
    
    int main()
    {
        while( scanf("%I64d" , &n) != EOF )
        {
            queue<int>Q[2];
            for(long long i=0; i<n; i++)
            {
                read(v[i]);
            }
            for(long long i=0; i<n; i++)
            {
                read(t);
                ans = 0;
                num = i%2;
                Q[num].push(v[i]);
                while( !Q[num].empty() )
                {
                    f = Q[num].front();
                    Q[num].pop();
                    if( f >= t)
                    {
                        ans += t;
                        Q[!num].push(f-t);
                    }
                    else
                    {
                        ans += f;
                    }
                }
                if(i != 0)
                    printf(" %I64d" , ans);
                else
                    printf("%I64d" , ans);
            }
            printf("
    ");
    
        }
    
    
        return 0;
    }
    第十一组超时

    写法不对 第四组就超时

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    
    using namespace std;
    
    int n , v[100010] , t[100010];
    int sum[100010];
    int ans[100010];
    
    int fin(int x)
    {
        int l , r , mid , res;
        l = x;
        r = n;
        res = n+1;
        while( l<= r)
        {
            mid = (l+r)/2;
    //        printf("%d......%d.....%d
    " , l , r , mid);
            if((sum[mid]-sum[x]+t[x]) >= v[x])
            {
                res = mid;
                r = mid-1;
            }
            else
            {
                l = mid+1;
            }
        }
        return res;
    }
    
    int main()
    {
        sum[0] = 0;
        while( scanf("%d" , &n) != EOF )
        {
            memset(ans , 0 , sizeof(ans));
            for(int i=1; i<=n; i++)
            {
                scanf("%d" , &v[i]);
            }
            for(int i=1; i<=n; i++)
            {
                scanf("%d" , &t[i]);
                sum[i] = sum[i-1]+t[i];
            }
            for(int i=1; i<=n; i++)
            {
                int r = fin(i);
    //            printf(".......%d
    " , r);
                if(sum[r]-sum[i]+t[i]==v[i])
                {
                    for(int j=i; j<=r; j++)
                        ans[j] += t[j];
                }
                else
                {
                    for(int j=i; j<r; j++)
                        ans[j] += t[j];
                    ans[r] += v[i]-(sum[r-1]-sum[i]+t[i]);
                }
                if(i!=1)
                printf(" %d" , ans[i]);
                else if(i==1)
                    printf("%d" , ans[i]);
            }
    
        }
    
        return 0;
    }
    第四组超时

    将数组修改为两个数组f[]数组记录会融化多少个完整的t体积  w记录会融化多少个剩余的体积 最后用f[]*t[]+w[]  会到十一组超时

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    
    using namespace std;
    
    long long n , v[100010] , t[100010];
    long long sum[100010];
    long long f[100010];
            long long w[100010];
    
    long long fin(long long x)
    {
        long long l , r , mid , res;
        l = x;
        r = n;
        res = n+1;
        while( l<= r)
        {
            mid = (l+r)/2;
    //        printf("%I64d......%I64d.....%I64d
    " , l , r , mid);
            if((sum[mid]-sum[x]+t[x]) >= v[x])
            {
                res = mid;
                r = mid-1;
            }
            else
            {
                l = mid+1;
            }
        }
        return res;
    }
    
    int main()
    {
        sum[0] = 0;
        while( scanf("%I64d" , &n) != EOF )
        {
            memset(f , 0 , sizeof(f));
            memset(w , 0 , sizeof(w));
            for(long long i=1; i<=n; i++)
            {
                scanf("%I64d" , &v[i]);
            }
            for(long long i=1; i<=n; i++)
            {
                scanf("%I64d" , &t[i]);
                sum[i] = sum[i-1]+t[i];
            }
            for(long long i=1; i<=n; i++)
            {
                long long r = fin(i);
    //            printf(".......%I64d
    " , r);
                    for(long long j=i; j<r; j++)
                        f[j]++;
                    w[r] += v[i]-(sum[r-1]-sum[i]+t[i]);
                if(i!=1)
                    printf(" %I64d" , f[i]*t[i]+w[i]);
                else if(i==1)
                    printf("%I64d" , f[i]*t[i]+w[i]);
            }
    
        }
    
        return 0;
    }
    第十一组超时

     把f[]不设置成全部更新 只设置成更新断电 逐渐累加过去 这个是个小技巧 要记住  还有就是特殊样例

    4

    0 0 0 0

    1 2 3 4

    需要试一下

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    
    using namespace std;
    
    long long n;
    long long v[100010] , t[100010];
    long long sum[100010];
    long long f[100010] , w[100010];
    
    long long fin(long long x)
    {
        v[x] += sum[x-1];
        long long l = 1;
        long long r = n;
        long long mid;
        long long res;
        res = n+1;
        while( l <= r)
        {
            mid = (l+r)/2;
            if(sum[mid] >= v[x])
            {
                res = mid;
                r = mid-1;
            }
            else
            {
                l = mid+1;
            }
        }
        return res;
    
    }
    
    int main()
    {
        sum[0] = 0;
        while( scanf("%I64d" , &n) != EOF )
        {
            memset(f , 0 , sizeof(f));
            memset(w , 0 , sizeof(w));
            for(long long i=1; i<=n; i++)
            {
                scanf("%I64d" , &v[i]);
            }
            for(long long i=1; i<=n; i++)
            {
                scanf("%I64d" , &t[i]);
                sum[i] = sum[i-1]+t[i];
            }
            long long zz;
            zz = 0;
            for(long long i=1; i<=n; i++)
            {
                long long r = fin(i);
    //            printf("%I64d.........
    " , r);
                if(r>i && r != i)
                {
                    f[i]++;
                    f[r]--;
                    w[r] += v[i]-sum[r-1];
                }
                else
                {
                    w[i] += v[i]-sum[i-1];
                }
                zz += f[i];
                if(i!=1)
                    putchar(' ');
                printf("%I64d" , zz*t[i]+w[i]);
            }
            printf("
    ");
        }
    
    
        return 0;
    }
    

      

  • 相关阅读:
    c语言面试
    汇编面试基础
    求余符号的用法
    ++a和a++的一点不同
    OVER子句
    SQL执行计划解析(1) 执行计划基础
    sql 排序规则 chinese_prc_ci_as
    SQL执行计划解析(2) 基本查询的图形执行计划
    过sql_trace跟踪得到了该SQL的执行计划,如何看懂执行计划
    JS日历控件集合附效果图、源代码
  • 原文地址:https://www.cnblogs.com/Flower-Z/p/8584291.html
Copyright © 2020-2023  润新知