【Educational Codeforces Round28】

咸鱼选手发现自己很久不做cf了,晚节不保。

A.Curriculum Vitae

枚举一下间断点的位置。

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int cnt,n,a[N],mx,cur;
inline int read(){
    int f=1,x=0;char ch;
    do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘);
    do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘);
    return f*x;
}
int main(){
    n=read();
    for(int i=1;i<=n;i++)a[i]=read();
    int flag=0;
    for(int i=1;i<=n;i++){
        cur=0;for(int j=1;j<=i;j++)if(a[j]==0)cur++;
        for(int j=i;j<=n;j++)if(a[j]==1)cur++;
        mx=max(mx,cur);
    }
    printf("%d\n",mx);
}

B. Math Show

枚举完成了哪些套装,然后剩下的贪心算就好。

#include<bits/stdc++.h>
const int N=50;
typedef long long ll;
using namespace std;
int n,m;
ll a[N],cur,tot,ans,qwq,k;
int vis[N];
inline ll read(){
    ll f=1,x=0;char ch;
    do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘);
    do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘);
    return f*x;
}

int main(){
    n=read();k=read();m=read();
    for(int i=1;i<=k;i++)a[i]=read(),tot+=a[i];
    sort(a+1,a+k+1);
    if(m>=tot*n){
        ans=1LL*n*(k+1);cout<<ans<<endl;return 0;
    }
    for(int i=0;i<=n;i++){
        ll res=m-1LL*i*tot;
        if(res<0)continue;
        ll cur=0;cur+=1LL*i*(k+1);ll qwq=n-i;
        if(res==0){ans=max(ans,cur);continue;}
        for(int j=1;j<=k;j++){
            if(qwq*a[j]<=res){res-=qwq*a[j];cur+=qwq;if(res<=0)break;continue;}
            if(res<=0)break;
            ll q=res/a[j];cur+=q;break;
        }
        ans=max(ans,cur);
    }
    cout<<ans<<endl;
}

老年选手晚节不保,一开始还以为尽量多做整套。

我是傻逼。

C. Four Segments

化简一下式子,然后就可以枚举了。

#include<bits/stdc++.h>
typedef long long ll;
const int N=1000010;
using namespace std;
ll s[N],n,ans,x,y,z;
inline ll read(){
    ll f=1,x=0;char ch;
    do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘);
    do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘);
    return f*x;
}
int main(){
    n=read();
    for(int i=1;i<=n;i++)s[i]=s[i-1]+read();
    for(int i=0;i<=n;i++){
        ll cur=s[i],now=i;
        for(int j=i;j<=n;j++){
            if(s[j]<cur)cur=s[j],now=j;
            if(s[i]-s[now]+s[j]>ans)ans=s[i]-s[now]+s[j],x=i,y=now,z=j;
        }
    }
    printf("%I64d %I64d %I64d\n",x,y,z);
}

D. Monitor

维护一个二维的前缀和。然后做k次拓展,这样每个点管的就是一个向上k的矩形。

剩下的就是横向的区间max,500的范围老年选手选择失去梦想的n^3暴力。

#include<bits/stdc++.h>
const int N=610;
using namespace std;
int n,m,k,q,inf;
int a[N][N];
struct Point{int x,y,t;}p[10000010];
inline int read(){
    int f=1,x=0;char ch;
    do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘);
    do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘);
    return f*x;
}
inline int querymax(int o,int l,int r){
    int ans=0;
    for(int i=l;i<=r;i++)ans=max(a[o][i],ans);
    return ans;
}
int ans=0;
int main(){
    n=read();m=read();k=read();q=read();
    memset(a,127,sizeof(a));inf=a[1][1];ans=inf;
    for(int i=1;i<=q;i++){
        p[i].x=read();p[i].y=read();p[i].t=read();
        a[p[i].x][p[i].y]=p[i].t;
    }
    for(int qwq=1;qwq<k;qwq++)
    for(int i=1;i<n;i++)for(int j=1;j<=m;j++)a[i][j]=max(a[i][j],a[i+1][j]);
    for(int i=1;i+k-1<=n;i++)for(int j=1;j+k-1<=m;j++)
    ans=min(ans,querymax(i,j,j+k-1));
    if(ans==inf)puts("-1");else printf("%d\n",ans);
}

E. Chemistry in Berland

关系会形成一棵树,这很显然。

然后就是考虑节点之间的关系,这个关系其实就是树的拓扑序,一边对树拓扑排序一边dp一下,从下面开始先试图用父亲节点满足子节点

多余的上传到父亲节点即可。

#include<bits/stdc++.h>
const int N=100005;
typedef long long ll;
const ll inf=(1LL<<60)-1;
using namespace std;
ll a[N],b[N],dp[N];
int n,m,tot,head[N];
struct Edge{int u,v,next;ll w;}G[N<<1];
inline void addedge(int u,int v,ll w){
    G[++tot].u=u;G[tot].v=v;G[tot].w=w;G[tot].next=head[u];head[u]=tot;
    G[++tot].u=v;G[tot].v=u;G[tot].w=w;G[tot].next=head[v];head[v]=tot;
}
inline void dfs(int u,int f){
    dp[u]=b[u]-a[u];
    for(int i=head[u];i;i=G[i].next){
        int v=G[i].v;ll w=G[i].w;
        if(v==f)continue;
        dfs(v,u);
        if(dp[v]<0){
            if(-dp[v]<inf/w)dp[u]+=dp[v]*w;
            else dp[u]=-inf;
            if(dp[u]<-inf)dp[u]=-inf;
        }
        else dp[u]+=dp[v];
    }
}
inline ll read(){
    ll f=1,x=0;char ch;
    do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘);
    do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘);
    return f*x;
}
int main(){
    n=read();
    for(int i=1;i<=n;i++)b[i]=read();
    for(int i=1;i<=n;i++)a[i]=read();
    for(int i=2;i<=n;i++){
        int x=read();ll k=read();
        addedge(i,x,k);
    }
    dfs(1,0);
    puts(dp[1]>=0?"YES":"NO");
}

F. Random Query

这种题栋老师怕不是随便秒。

考虑一个数对区间的贡献,重复的数记录最后一次出现的位置,最后除所有可能即可。

#include<bits/stdc++.h>
const int N=1000010;
typedef long long ll;
using namespace std;
int n,m,a[N],b[N];
ll ans=0;
inline int read(){
    int f=1,x=0;char ch;
    do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘);
    do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘);
    return f*x;
}
int main(){
    n=read();
    for(int i=1;i<=n;i++)a[i]=read();
    ll ans=0,t=0;
    for(int i=1;i<=n;i++){
        t+=i-b[a[i]];ans+=t;b[a[i]]=i;
    }
    printf("%.6lf\n",(ans*2-n)/(double)(1LL*n*n));
}

总结:

1.注意想清楚特判,在提交之前想清楚所有可能情况以及特殊、极端的情况,不要想当然,防止晚节不保

2.看清楚数据范围,做多次确认。

时间: 2024-10-14 11:06:04

【Educational Codeforces Round28】的相关文章

【Educational Codeforces Round20】

这场edu有点简单-- 所以题目可能也有点奇奇怪怪的. A.随意构造一下,可以发现只有当填满都不行时才可能无解. #include<bits/stdc++.h> using namespace std; int n,k,a[105][105]; inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getc

【Educational Codeforces Round 35 A】 Nearest Minimums

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 找出最小的数字的位置. 最近的肯定是相邻的某对. [代码] #include <bits/stdc++.h> using namespace std; const int N = 1e5; int n; int a[N+10],mi; int main(){ #ifdef LOCAL_DEFINE freopen("rush_in.txt", "r", stdin); #endif io

【Educational Codeforces Round 35 D】Inversion Counting

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 排列中交换任意两个数字. 排列的逆序对个数的奇偶性会发生变化. 翻转这个过程其实就是len/2对数字发生交换. 交换了偶数次的话,不变,否则奇偶性发生改变. 先暴力求出一开始的逆序对个数就好 [代码] #include <bits/stdc++.h> using namespace std; const int N = 1500; int n,a[N+10],cnt,now,m; void out(int x){ if (x=

【Educational Codeforces Round 35 C】Two Cakes

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 直觉题. 感觉情况会很少. 毕竟间隔太大了.中间肯定有一些数字达不到. 有1肯定可以 2 2 x肯定可以 3 3 3也可以 2 4 4也可以. 就这样 [代码] #include <bits/stdc++.h> using namespace std; vector <int> v; int main(){ #ifdef LOCAL_DEFINE freopen("rush_in.txt", &

【Educational Codeforces Round 36 A】 Garden

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 枚举用哪一个桶就好 [代码] #include <bits/stdc++.h> using namespace std; int n,k,x; int main(){ #ifdef LOCAL_DEFINE freopen("rush_in.txt", "r", stdin); #endif ios::sync_with_stdio(0),cin.tie(0); cin >>

【Educational Codeforces Round 37 C】 Swap Adjacent Elements

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 显然l..r这一段连续的1可以把l..r+1变成有序的. 那么就把所有的连续1段变成有序的就好. 看看最后是不是升序即可. [代码] #include <bits/stdc++.h> using namespace std; const int N = 2e5; int n,a[N+10],b[N+10]; char s[N+10]; int main(){ #ifdef LOCAL_DEFINE freopen("

【Educational Codeforces Round 37 E】Connected Components?

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] bfs. 用一个链表来记录哪些点已经确定在某一个联通快里了. 一开始每个点都能用. 然后从第一个点开始进行bfs. 然后对于它的所有连接着的点(输入的图的补图 看看它是不是之前进行过bfs,如果是的话.就跳过.(可以用链表直接跳过.即沿着链表枚举它的出度. 否则.把这个点从链表中删掉.然后把这个点加入队列.继续bfs即可. 这样已经确定联通了的点之间不会再访问. 链表加速了寻找某个点的出度的过程. 且由于当n很大的时候.m只有2

【Educational Codeforces Round 37 A】 Water The Garden

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 记录下水龙头在哪些位置. 然后每秒钟把index-i和index+i改变状态一下就好(置1 [代码] #include <bits/stdc++.h> using namespace std; const int N = 200; int n,k; int a[N+10],x[N+10]; int ok(){ for (int i = 1;i <= n;i++) if (a[i]==0) return 0; return

【Educational Codeforces Round 81 (Rated for Div. 2) A】Display The Number

题目链接 [题解] 优先用2个棒子来凑1. 如果为奇数的话,多出来一根用3根来凑个7放在开头 [代码] #include <bits/stdc++.h> using namespace std; int main(){ #ifdef LOCAL_DEFINE freopen("E:\\rush.txt","r",stdin); #endif // LOCAL_DEFINE ios::sync_with_stdio(0),cin.tie(0); int T