首页 > 其他分享 >AcWing 133/洛谷2827 蚯蚓

AcWing 133/洛谷2827 蚯蚓

时间:2022-09-21 21:34:36浏览次数:58  
标签:rd 洛谷 int d% long 133 队列 2827 蚯蚓

首先考虑根据题意模拟

#include<bits/stdc++.h>
#define int long long//懒死谁了
using namespace std;
typedef long long ll
inline void rd(int &x) {
    x=0;
    bool w=0;
    char ch1;
    ch1=getchar();
    while(!isdigit(ch1)) {
      ch1=='-'&&(w=1);
      ch1=getchar(); 
    }
    while(isdigit(ch1)) { 
      x=(x<<1)+(x<<3)+(ch1&15);
      ch1=getchar();
    }
    w&&(x=(~x)+1);
}
priority_queue<int>q;//只用一个优先队列维护所有蚯蚓长度
signed main()
{
//    freopen("test.in","r",stdin);
//    freopen("test.out","w",stdout);
    int n,m,qq,u,v,t,a;
    //n蚯蚓数 m剩余时间 q增加的长度  p=u/v  t每t次输出一次
//    scanf("%d%d%d%d%d%d",&n,&m,&qq,&u,&v,&t);
    rd(n);rd(m);rd(qq);rd(u);rd(v);rd(t);
    for(int i=1;i<=n;i++)
    {
//        scanf("%d",&a);//蚯蚓初始长度
        rd(a);
        q.push(a);//扔进去!
    }
    int delta=0;//维护一个delta 队列中的蚯蚓长度+delta为真实长度
    for(int i=1;i<=m;i++)
    {
        int s=q.top()+delta;//最长的蚯蚓长度
        q.pop();//别忘了qwq
        int ss=s*u/v;//被切断后的长度
        q.push(ss-delta-qq);
        q.push(s-ss-delta-qq);
        delta+=qq;
        if(i%t==0) 
        printf("%lld ",s);//t次了就输出
    }
    printf("\n");
    for(int i=1;q.size();i++)
    {
        int tt=q.top()+delta;
        q.pop();
        if(i%t==0)
        printf("%lld ",tt);
        //刚开始变量名重了.....
    }
    return 0;
}

预计得分80  实际得分85

似乎正解但是被AcWing卡了:

用三个队列维护  最后全部push进优先队列里

洛谷100 AcWing差一个点

//和正解很像 正解写了详细注释 这个就不写了
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
const int maxn=7e7+9;
int a[maxn],b[maxn],c[maxn];
priority_queue<int>q;
bool comp(int a,int b)
{
    return a>b;
}
int t0,t1,t2,h=1,h1=1,h2=1,cnt,delta;
signed main()
{
    int n,m,qq,u,v,t;
    scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&qq,&u,&v,&t);
    for(t0=1;t0<=n;t0++)
    {
        scanf("%lld",&a[t0]);
    }
    sort(a+1,a+n+1,comp);
    t0--;
    for(int i=1;i<=m;i++)
    {
        if(h>t0) {
            if(b[h1]>c[h2]) {
                cnt=b[h1++];
            }
            else {
                cnt=c[h2++];
            }
        }
        else if(a[h]>=b[h1]&&a[h]>=c[h2]) {
            cnt=a[h++];
        }
        else if(b[h1]>=c[h2]&&a[h]<=b[h1]) {
            cnt=b[h1++];
        }
        else {
            cnt=c[h2++];
        }
        cnt+=delta;
        int a1=u*cnt/v;
        int a2=cnt-a1;
        delta+=qq;
        a1-=delta;
        a2-=delta;
        b[++t1]=a1;
        c[++t2]=a2;
        if(i%t==0) {
            printf("%lld ",cnt);
        }
    }
    printf("\n");
    //全部push进堆里
    for(int i=h;i<=t0;i++)
    {
        q.push(a[i]);
    }
    for(int i=h1;i<=t1;i++)
    {
        q.push(b[i]);
    }
    for(int i=h2;i<=t2;i++)
    {
        q.push(c[i]);
    }
    for(int i=1;q.size();i++)
    {
        if(i%t==0) {
            printf("%lld ",q.top()+delta);
        }
        q.pop();
    }
    return 0;
}

 

正解:

用一次排序保证单调 用三个队列维护长度

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e7+10;
queue<ll>p1,p2,p3;
//q1原蚯蚓队列  q2切断后的左半段蚯蚓队列   q3右半段
int n,m,q,t;
ll a[maxn],u,v;
bool comp(ll a,ll b)
{
    return a > b;
    //将最长的放在队首
}
int find(int t)
//在三个队列里查找最长的蚯蚓长度
//t是已经经过了t秒
{
    int x=-1,a=-1,b=-1,c=-1;
    //全部赋初值防止有队列已空出错
    //可能存在长度为0的蚯蚓 所以初值是-1
    if(!p1.empty()) {
        a=p1.front()+t*q;
    }
    if(!p2.empty()) {
        b=p2.front()+t*q;
    }
    if(!p3.empty()) {
        c=p3.front()+t*q;
    }
    //取出每个队首
    x=max(a,max(b,c));//比较
    if(x==a) {
        p1.pop();
    }
    else if(x==b) {
        p2.pop();
    }
    else if(x==c) {
        p3.pop();
    }
    //找出属于哪个队列并弹出队列
    return x;
}
signed main()
{
    scanf("%d%d%d%lld%lld%d",&n,&m,&q,&u,&v,&t);
    //n为初始蚯蚓个数 m为一共切几次蚯蚓  q为每次增加的长度  
    //切成多少u/v和1-u/v两段  t是每几次输出一次
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        //输入初始蚯蚓长度
    }
    sort(a+1,a+1+n,comp);
    //排序 找最长的蚯蚓
    for(int i=1;i<=n;i++)
    {
        p1.push(a[i]);
        //将初始蚯蚓长度存进队列
    }
    for(int i=1;i<=m;i++)//每秒战况
    {
        ll x=find(i-1);
        if (!(i%t)) {
            printf("%lld ",x);
        }
        ll s1=x*u/v;
        ll s2=x-s1;
        //被切断后的两段蚯蚓长度 
        p2.push(s1-i*q);
        p3.push(s2-i*q);
        //由于q1内的蚯蚓长度是单调的 并且u/v的值没变  
        //所以切断后的蚯蚓长度也是单调的 用队列维护就行
    }
    printf("\n");
    for(int i=1;i<=(n+m);i++)
    //初始n条 每秒增加一条 经过m秒 所以一共有n+m条蚯蚓
    {
        ll x=find(m);
        //按从长到短的顺序每t个输出一次
        if (!(i%t)) {
            printf("%lld ",x);
        }
    }
    return 0;
}

 

标签:rd,洛谷,int,d%,long,133,队列,2827,蚯蚓
From: https://www.cnblogs.com/Mercury1004/p/16717201.html

相关文章

  • 洛谷P1290 欧几里德的游戏
    链接:https://www.luogu.com.cn/problem/P1290不妨假设\(b\leqa\)。显然,当\(a\)是\(b\)的倍数时,为必胜态。接下来考虑\(a\)不为\(b\)的倍数时:1.\(a\)小于\(2*b\)时,当前......
  • 洛谷P3372【模板】线段树1
    #include<bits/stdc++.h>usingnamespacestd;constintN=1e6+5;intn,m,a[N];intadd[N*4];//账本longlongsum[N*4];//a[k]的区间和voidbuild(intk,intl,i......
  • 洛谷真题字典树
    P8306【模板】字典树1#include<bits/stdc++.h>2usingnamespacestd;3intt,n,q;4constintmaxn=3000005;5chars[maxn];6intson[maxn][80],cnt[ma......
  • 洛谷 P1123 取数游戏(dfs)
    https://www.luogu.com.cn/problem/P1123题目大意:给定一个n*m的矩阵,问我们从里面怎样取能取到最大的总和?条件是选了一个数,下次它的八个方向上的数字就不能选了输入#1......
  • CF1338D Nested Rubber Bands
    考虑答案在树上长什么样子。首先答案肯定是一个独立集,因为两两之间没有交。对于相邻两个圆,他一定是经过中间一个点来连接的,画个图容易发现中间的这个点连接的所有点都能......
  • 洛谷P1262 间谍网络(tarjan求强连通分量+缩点)
    题目链接:https://www.luogu.com.cn/problem/P1262思路:首先,我们能够知道,入读为0的点如果不能被收买的话,那么此题是无解的。其次,如果图中存在环的话,那么环中每个点的......
  • 洛谷P2002 消息扩散(tarjan缩点)
    题目链接:https://www.luogu.com.cn/problem/P2002思路:由于图中每个强连通分量(scc)中的点是可以互相到达的,所以我们可以用tarjan求图中scc,然后将所有scc缩点,最后求缩点之......
  • 洛谷 P1036 [NOIP2002 普及组] 选数(dfs)
    https://www.luogu.com.cn/problem/P1036题目大意:从给定的n个数中选出m个求和,结果是一个素数的情况有多少种?输入43371219输出1这个题目的代码是根据Acwing中......
  • LeetCode — 133. 克隆图
    LeetCode—133.克隆图这是LeetCode的解决方案——133.克隆图.对于这个问题,我们使用DFS。通过记录访问过的节点(值是克隆值)地图,并在每次递归时查询它是否被访......
  • 20201330马榕辰第一,二章学习笔记
    第一章: 一.知识点归纳:第一章前半部分重在介绍课程和书本的基本情况,包括Unix / Linux的历史,其各种发行版,我了解到了一些基本情况。后半部分主要是 Linux的使用,Lin......