CodeForces - 948C 解题报告

题目链接

这道题看出来了是一道STL题,本来一开始用队列去做,结果TLE,在这里先给出TLE代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 1e5 + 10;
int n,V[maxn],T[maxn];

int main()
{
    while(scanf("%d",&n)==1)
    {
        for(int i=0;i<n;i++) scanf("%d",&V[i]);
        for(int i=0;i<n;i++) scanf("%d",&T[i]);

        queue<int > que;
        for(int i=0;i<n;i++)
        {
            que.push(V[i]);
            ll cnt=0;
            int len=que.size();
            for(int j=0;j<len;j++)
            {
                int vi=que.front(); que.pop();
                if(vi>T[i])
                {
                    cnt+=T[i];
                    que.push(vi-T[i]);
                }
                else cnt+=vi;
            }
            if(i) printf(" ");
            printf("%lld",cnt);
        }
        printf("\n");
    }
    return 0;
}

原因是,第二个循环逐个去统计维护,会消耗大量时间,但是思路比较简单

比赛完后看了其他大佬的代码发现都是用优先队列做的,而且在统计方面也是很精炼,大家可以多注意一下,下面代码在计数方面的技巧:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 1e5 + 10;
int n,V[maxn],T[maxn];

int main()
{
    scanf("%d",&n);
    for(int i=0; i<n; i++) scanf("%d",&V[i]);
    for(int i=0; i<n; i++) scanf("%d",&T[i]);

    priority_queue<ll,vector<ll>,greater<ll> > que;
    ll sum=0;
    for(int i=0; i<n; i++)
    {
        que.push(V[i]+sum);// 每次都加上sum是为了防止以前对现在刚加入得影响
        ll cnt=0;
        while(!que.empty())
        {
            ll vi=que.top();
            if(vi-T[i]-sum>0) break;
            cnt+=vi-sum;//若今天会融化完全,则加上,今天的剩余量
            que.pop();
        }
        sum+=T[i];
        cnt+=(ll)que.size()*T[i];
        if(i) printf(" ");
        printf("%lld",cnt);
    }
    printf("\n");
    return 0;
}

本题还有一个容易WA的地方就是数据的范围,唉,不知道吃了多少次亏了,还是没长记性,所有的数据除了一开始读的,后面计数的数据都要用ll,注意是所有的!!!一次全部改完(别问我为什么这样说)。

猜你喜欢

转载自blog.csdn.net/NCC__dapeng/article/details/81975836