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