其他分享
首页 > 其他分享> > Codeforces Round #576 (Div. 2) A,B,C,D

Codeforces Round #576 (Div. 2) A,B,C,D

作者:互联网

Codeforces Round #576 (Div. 2) A,B,C,D

前言

太久没训练的回坑比赛,手感略生,整体表现还算OK,但是还可以更进一步。stonebamboo 1546->1609
开局电脑略卡15min过的A,其中还是有几个小点没有调的出来,B题比较简答,还算较快,19min出的。 C,D比较慢,思路还算比较清晰,但是走了一些弯路,88min分钟出C,110min出D,希望还是可以再快一点吧,下面应该也会陆陆续续补一些前面没打的cf,希望下半年的区域赛能出成绩,加油。

A. City Day

题意
给定n天的降水量,找到前x天和后y天里面降水量最小的一天。
做法
简单的暴力就行了,但是要注意,无论是前还是后,如果不在这n天之内的就可以不考虑,其实质就是在找一定天数内的最小值
代码

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int a[100010];
int main()
{
    int x,y,n;
    scanf("%d%d%d",&n,&x,&y);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    a[n] = 0x3f3f3f3f;
    for(int i=0;i<n;i++)
    {
        bool judge = true;
        for(int j=1;j<=x&&i-j>=0;j++)
        {
            if(a[i-j]<a[i])
            {
                judge = false;
            }
        }
        for(int j=1;j<=y&&i+j<n;j++)
        {
            if(a[i+j]<a[i])
            {
                judge = false;
            }
        }
        if(judge)
        {
            printf("%d\n",i+1);
            return 0;
        }
    }
}

B. Water Lily

题意
给定一株水仙露出水面的长度以及浮于水面上时偏移的距离,求水池的深度。
做法
简单的数学问题,设水深X,勾股定理求解,最后结果是(ll-hh)/(2*h),注意浮点数
代码

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int a[100010];
int main()
{
    double h,l;
    scanf("%lf%lf",&h,&l);
    printf("%lf\n",(l*l-h*h)/(2*h));
}

C. MP3

题意
对一段MP3的数据音频进行压缩,使得声音密度满足一定的条件,我们只可以选定一定的区间,然后将这个区间之外的所有的值改变成这个区间内的值,问,如何选取这个区间可以使得我们改变的次数尽可能地少,最少需要多少次。
做法
首先按照题意要求求出声音密度K的值,然后将所有的数据进行排序,对排序后的数据的每一段相同的数据进行计数,将计数结果记入一个数组,然后取数组中的一段进行取max,最后得到我们想要的结果。
代码

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int a[400010];
int cnt[400010];
int main()
{
    int n,I;
    scanf("%d%d",&n,&I);
    for(int i=0; i<n; i++)
    {
        scanf("%d",&a[i]);
    }
    sort(a,a+n);
    int k = I*8/n;
    k = min(k,20);        //这个地方是为了保证K的大小不会太大,实际上因为总数是有限的,当k大于20时是没有意义的
    int K = 1<<k;
    int t = 0;
    int tmp = 1;
    for(int i=1; i<n; i++)
    {
        if(a[i]==a[i-1]) tmp++;
        else
        {
            cnt[t++]=tmp;
            tmp = 1;
        }
    }
    cnt[t++] = tmp;
    if(K>=t)
    {
        printf("0\n");
        return 0;
    }
    int maxn = 0;
    int tmpcnt = 0;
    for(int j=0; j<K; j++)
    {
        tmpcnt += cnt[j];
    }
    maxn = tmpcnt;
    for(int i=K; i<t; i++)
    {
        tmpcnt -= cnt[i-K] ;
        tmpcnt += cnt[i];
        maxn = max(maxn,tmpcnt);
    }
    printf("%d\n",max(n-maxn,0));
}

D. Welfare State

题意
给定一些数据,有两种操作,第一种是将指定位置的数改变成指定的数x,第二种是将所有比指定的数y小的数都变为y。给出执行完所有操作最后剩余的数据。
做法
记录每一次第二种操作的操作数,对每一次的第一种操作,记录他是在第几个第二次操作之后执行的,对记录第二种操作的操作数的数组从后往前进行相邻两项取max,然后对于每一个第一种操作,与它后一次的操作数进行比较,如果没有,则输出自身。
代码

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int a[200010];
int c[200010];
int oper[200010][3];
int cn[2000010];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
    }
    memset(c,0,sizeof(c));
    int q;
    scanf("%d",&q);
    int maxn = 0;
    int sign = 0;
    int tmp = 0;
    int t = 0;
    for(int i=0; i<q; i++)
    {
        scanf("%d",&oper[i][0]);
        if(oper[i][0]==1)
        {
            scanf("%d%d",&oper[i][1],&oper[i][2]);
            int x = oper[i][1];
            int y = oper[i][2];
            a[x] = y;
            c[x] = 1;
            tmp = max(tmp,y);
        }
        else
        {
            scanf("%d",&oper[i][1]);
            if(oper[i][1]>maxn)
            {
                maxn = oper[i][1];
                sign = i;
            }
            if(tmp!=0&&tmp<oper[i][1])
            {
                sign = i;
                tmp = 0;
            }
        }
    }
    for(int i=0; i<q; i++)
    {
        if(oper[i][0]==1)
        {
            int x = oper[i][1];
            int y = oper[i][2];
            a[x] = y;
            c[x] = t;
        }
        else
        {
            cn[t++] = oper[i][1];
        }
    }
    for(int i=t-1;i>0;i--)
    {
        cn[i-1] = max(cn[i],cn[i-1]);
    }
    for(int i=1; i<=n; i++)
    {
        if(a[i]<cn[c[i]]&&c[i]<t) printf("%d ",cn[c[i]]);
        else printf("%d ",a[i]);
    }
}

后话
这段代码实际上不是特别简洁的,但是其中也包含了作者的一些思路变化,所有就不太愿意改动,读者可以试着自己去改进一下,毕竟ACM的训练从模仿开始,一定是到自己学会写为止。

标签:题意,int,ll,576,long,Codeforces,using,Div,include
来源: https://blog.csdn.net/qq_42680479/article/details/97946054