• 洛谷P2827 蚯蚓——思路题


    题目:https://www.luogu.org/problemnew/show/P2827

    思路...

    用优先队列模拟做的话,时间主要消耗在每次的排序上;

    能不能不要每次排序呢?

    关注先后被砍的两条蚯蚓 x 和 y,发现砍完以后,它们的两部分对应还满足原来的大小关系!

    从两条蚯蚓出发,可以推知所有蚯蚓砍完以后的两部分还对应满足原来的大小关系;

    但两部分之间就不一定了;

    所以开三个队列,分别记录原来的蚯蚓,砍后第一部分的蚯蚓,砍后第二部分的蚯蚓;

    每次取三个队列中最长的蚯蚓砍,砍出来的两部分对应加到砍后的两个队列里;

    即使是又砍了已经被砍过的蚯蚓,把它类比成原来的蚯蚓,也满足刚才的那种做法;

    于是这题就A了;

    有不少细节呢,而且注意要开 long long !以后应该对这些敏感一点;

    由这题得到的经验是,遇到关于询问大小关系,没有规律,需要不断排序的问题的时候,关注相邻的两个量的变化关系,也许能有意想不到的发现。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    queue<pair<ll,int> >q1,q2,q3;
    priority_queue<int>ans;
    int const maxn=1e5+5;
    int n,m,q,u,v,t,a[maxn];
    int main()
    {
        scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        for(int i=n;i;i--)q1.push(make_pair(a[i],1));//1
        ll x,x1,x2,x3;
        for(int i=1;i<=m;i++)
        {
            x1=0; x2=0; x3=0;
            if(q1.size()) x1=q1.front().first+q*(i-q1.front().second);
            if(q2.size()) x2=q2.front().first+q*(i-q2.front().second);
            if(q3.size()) x3=q3.front().first+q*(i-q3.front().second);
            if(q1.size() && (!q2.size()||x1>=x2) && (!q3.size()||x1>=x3)) x=x1,q1.pop();//=
            else if(q2.size() && (!q1.size()||x2>=x1) && (!q3.size()||x2>=x3)) x=x2,q2.pop();//else
            else if(q3.size() && (!q1.size()||x3>=x1) && (!q2.size()||x3>=x2)) x=x3,q3.pop();
        
            if(i%t==0)printf("%lld ",x);
            q2.push(make_pair(x*u/v,i+1)); q3.push(make_pair(x-x*u/v,i+1));//i+1
        }
        printf("
    ");
        for(int i=1;i<=n+m;i++)
        {
            x1=0; x2=0; x3=0;
            if(q1.size()) x1=q1.front().first+q*(m+1-q1.front().second);
            if(q2.size()) x2=q2.front().first+q*(m+1-q2.front().second);
            if(q3.size()) x3=q3.front().first+q*(m+1-q3.front().second);
            if(q1.size() && (!q2.size()||x1>=x2) && (!q3.size()||x1>=x3)) x=x1,q1.pop();
            else if(q2.size() && (!q1.size()||x2>=x1) && (!q3.size()||x2>=x3)) x=x2,q2.pop();
            else if(q3.size() && (!q1.size()||x3>=x1) && (!q2.size()||x3>=x2)) x=x3,q3.pop();
            
            if(i%t==0)printf("%lld ",x);
        }
        return 0;
    }
  • 相关阅读:
    C#初识
    SQL 语言基础
    类;类型
    输入一元二次方程的三个参数,a,b,c,判断是否为一元二次方程,并求解
    输入一个1-100之内的数,判断是否跟7有关
    输入身高、体重、性别,判断是否是标准体重,男性标准=(身高-100)+-3,女性标准=(身高-110)+-3
    分别录入年月日,判断是否是一个正确的日期
    面向对象基础--面向对象思想(理解)
    2015-01-04 Javascript
    2014-12-28 iframe,style,body style
  • 原文地址:https://www.cnblogs.com/Zinn/p/9215359.html
Copyright © 2020-2023  润新知