Educational Codeforces Round 55 (Rated for Div. 2)

Educational Codeforces Round 55 (Rated for Div. 2)

链接

A Vasya and Book

傻逼题。。注意判边界。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cmath>
using namespace std;

typedef long long ll;

int t,n,x,y,d;

int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d%d%d",&n,&x,&y,&d);
        int sxz=abs(x-y);
        if(sxz%d==0) {
            printf("%d\n",sxz/d);
            continue;
        }
        int ans=0x7fffffff;
        if((y-1)%d==0)
            ans=min(ans,(x==1?0:(int)ceil((double)(x-1)/d))+(y-1)/d);
        if((n-y)%d==0)
            ans=min(ans,(x==n?0:(int)ceil((double)(n-x)/d))+(n-y)/d);
        if(ans==0x7fffffff) printf("-1\n");
        else printf("%d\n",ans);
    }
    return 0;
}

B Vova and Trophies

还是傻逼题。。还是要判好边界。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cmath>
using namespace std;

typedef long long ll;
const int Maxn=110000;

int n,a[Maxn],l[Maxn],ok[Maxn],tot;

char getach() {
    char ch=getchar();
    while(ch!=‘G‘&&ch!=‘S‘) ch=getchar();
    return ch;
}

int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        if(getach()==‘G‘) {
            a[i]=1;
            if(i>2&&a[i-1]==0&&a[i-2])
                ok[tot]=1;
            l[tot]++;
        }
        else if(a[i-1]) tot++;
    }
    if(a[n]==1) tot++;
    if(tot==1) {
        printf("%d",l[0]);
        return 0;
    }
    int ans=0;
    for(int i=0;i<tot;i++) {
        ans=max(ans,l[i]+1);
        if(ok[i]) {
            if(tot==2)
                ans=max(ans,l[i]+l[i-1]);
            else ans=max(ans,l[i]+l[i-1]+1);
        }
    }
    printf("%d",ans);
    return 0;
}

C Multi-Subject Competition

开n个堆就好了,用队列存着目前堆非空且和不为负数的堆分别是那几个,时间复杂度\(O(n \log n)\)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cmath>
using namespace std;

typedef long long ll;
const int Maxn=110000;

int n,m,c[Maxn],b[Maxn],ans,x,y,tot;

priority_queue<int> q[Maxn];

int main() {
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) {
        scanf("%d%d",&x,&y);
        q[x].push(y);
    }
    for(int i=1;i<=m;i++)
        if(!q[i].empty()&&q[i].top()>0) {
            b[++tot]=q[i].top();
            c[tot]=i;
            q[i].pop();
        }
    int num=0;
    for(int i=1;i<=tot;i++)
        num+=b[i];
    ans=max(ans,num);
    while(tot) {
        int sxz=tot;
        tot=0;
        num=0;
        for(int i=1;i<=sxz;i++)
            if(!q[c[i]].empty()&&b[i]+q[c[i]].top()>0) {
                b[++tot]=b[i]+q[c[i]].top();
                c[tot]=c[i];
                q[c[i]].pop();
            }
        for(int i=1;i<=tot;i++)
            num+=b[i];
        ans=max(ans,num);
    }
    printf("%d",ans);
    return 0;
}

D Maximum Diameter Graph

这个题可以贪心,把所有的点按照度数限制排个序,然后枚举直径的长度,直径两边选度数限制最小的,其余的点选度数限制最大的,然后把其他的点挂上就好了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cmath>
using namespace std;

typedef long long ll;
const int Maxn=110000;

int n,m,a[Maxn],b[Maxn];

int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]),b[i]=i;
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            if(a[j]>a[i]) {
                swap(a[i],a[j]);
                swap(b[i],b[j]);
            }
    for(int i=n-2;i>=1;i--) {
        int num=0;
        for(int j=1;j<=i;j++)
            if(a[j]>=2) num+=a[j]-2;
            else {
                num=-1;
                break;
            }
        if(num>=n-i-2) {
            printf("YES %d\n",i+1);
            printf("%d\n",n-1);
            printf("%d %d\n",b[n],b[1]);
            printf("%d %d\n",b[n-1],b[i]);
            for(int j=1;j<i;j++) printf("%d %d\n",b[j],b[j+1]);
            int temp=1;
            for(int j=i+1;j<=n-2;j++)
                if(a[temp]>2) {
                    a[temp]--;
                    printf("%d %d\n",b[temp],b[j]);
                }
                else {
                    while(a[temp]==2) temp++;
                    a[temp]--;
                    printf("%d %d\n",b[temp],b[j]);
                }
            return 0;
        }
    }
    puts("NO");
    return 0;
}

E Increasing Frequency

这道题是傻逼贪心,我竟然没看出来。。

大概就是记一下c出现个数的前缀和,然后枚举其他的每个数,把这个数在数列中出现的位置排个序,从前往后扫一遍,维护左右端点,然后对于一个区间,如果在这个区间中c的出现次数比这个数多,那就把这个区间扔掉。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

typedef long long ll;
const int Maxn=510000;
const double eps=1e-9;

int n,c,x,a[Maxn],ans;

priority_queue<int,vector<int>,greater<int> >h[Maxn];

int main() {
//  freopen("test.in","r",stdin);
    scanf("%d%d",&n,&c);
    for(int i=1;i<=n;i++) {
        scanf("%d",&x);a[i]=a[i-1];
        if(x==c) a[i]++;
        h[x].push(i);
    }
    for(int i=1;i<=500000;i++)
        if(i!=c&&!h[i].empty()) {
            int sxz=0,zhy=1,last=h[i].top();
            h[i].pop();
            ans=max(ans,zhy);
            while(!h[i].empty()) {
                int temp=h[i].top();
                h[i].pop();
                sxz+=a[temp]-a[last];
                zhy++;
                if(sxz>=zhy) {
                    sxz=0;
                    zhy=1;
                }
                ans=max(ans,zhy-sxz);
                last=temp;
            }
        }
    printf("%d",ans+a[n]);
    return 0;
}

F

毒瘤。。。

G Petya and Graph

这个题是个傻逼网络流。。我竟然没看出来。

大概就是最小割建图,把每个点和每个边建点,每个边从他的两个端点连边,流量为正无穷;从原点向所有的点连边,流量为点的点权;从所有边向汇点连边,流量为边权。


    memset(b,0,sizeof(b));
    b[s]=1;
    while(!q.empty()) {
        int now=q.front();q.pop();
        for(int i=first[now];i;i=nxt[i])
            if(w[i]&&b[to[i]]==0) {
                b[to[i]]=b[now]+1;
                q.push(to[i]);
            }
    }
    return b[t];
}

ll dfs(int root,int flow) {
    if(root==t) return flow;
    for(int i=first[root];i;i=nxt[i])
        if(w[i]&&b[to[i]]==b[root]+1) {
            int temp=dfs(to[i],min(flow,w[i]));
            if(temp) {
                w[i]-=temp;
                w[i^1]+=temp;
                return temp;
            }
        }
    return 0;
}

ll dinic() {
    ll ans=0,temp;
    while(bfs())
        while(temp=dfs(s,inf))
            ans+=temp;
    return ans;
}

int main() {
//  freopen("test.in","r",stdin);
    scanf("%d%d",&n,&m);
    s=0,t=n+m+1;
    for(int i=1;i<=n;i++) {
        scanf("%I64d",&x);
        add(s,i,x);
    }
    for(int i=1,sxz=n+1;i<=m;i++,sxz++) {
        scanf("%d%d%I64d",&u,&v,&x);
        add(u,sxz,inf);
        add(v,sxz,inf);
        add(sxz,t,x);
        ans+=x;
    }
    printf("%I64d",ans-dinic());
    return 0;
}

原文地址:https://www.cnblogs.com/shanxieng/p/10040043.html

时间: 2024-08-08 08:10:02

Educational Codeforces Round 55 (Rated for Div. 2)的相关文章

Educational Codeforces Round 55 (Rated for Div. 2) C. Multi-Subject Competition 【vector 预处理优化】

传送门:http://codeforces.com/contest/1082/problem/C C. Multi-Subject Competition time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output A multi-subject competition is coming! The competition has mm 

Codeforces 1082 C. Multi-Subject Competition-有点意思 (Educational Codeforces Round 55 (Rated for Div. 2))

C. Multi-Subject Competition time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output A multi-subject competition is coming! The competition has mm different subjects participants can choose from.

[Educational Codeforces Round 55 (Rated for Div. 2)][C. Multi-Subject Competition][时间复杂度]

https://codeforc.es/contest/1082/problem/C 题目大意:有m个类型,n个人,每个人有一个所属类型k和一个能力v,要求所选的类型的人个数相等并且使v总和最大(n,m<=1e5) 题解:用vector存下每种类型的各个v并且每种类型根据v按从大到小排序,然后处理出每种类型的前缀和,然后扫每种类型的所有前缀和,如果该类型在i处的前缀和大于0,则相应的ans[i]加上这个类型在i处的前缀和,最后求出max(ans[i])(1<=i<=n)即可. 注意:这题

Codeforces 1082 A. Vasya and Book-题意 (Educational Codeforces Round 55 (Rated for Div. 2))

A. Vasya and Book time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Vasya is reading a e-book. The file of the book consists of nn pages, numbered from 11 to nn. The screen is currently disp

Codeforces 1082 D. Maximum Diameter Graph-树的直径-最长链-构造题 (Educational Codeforces Round 55 (Rated for Div. 2))

D. Maximum Diameter Graph time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Graph constructive problems are back! This time the graph you are asked to build should match the following proper

codeforces Educational Codeforces Round 55 (Rated for Div. 2) C题 C. Multi-Subject Competition

这道题比赛时候没做出来,下来一看才发现是排序傻逼题. 把每个偏好的人做成一个vector,从大到小排序,做一个前缀和.然后将每种人数做一个桶,在桶里装每种科目选择人数为i的时候分数总和. 遍历每一维vector,把各个位置上面的vector加到sum数组中,最后sum数组里面挑出最大值. #include<bits/stdc++.h> using namespace std; typedef long long ll; vector<int> vec[100010];//vecto

Educational Codeforces Round 55 (Rated for Div. 2) B. Vova and Trophies

传送门 https://www.cnblogs.com/violet-acmer/p/10035971.html 题意: Vova有n个奖杯,这n个奖杯全部是金奖或银奖,Vova将所有奖杯排成一排,你最多可以交换其中两个奖杯,求最大的连续的金奖杯个数. 题解: 思路: 求出连续的金奖杯位置,找出每两个相邻的连续的金奖杯所能够形成的最大的连续的金奖杯的个数,输出最大值. 相关变量解释: 1 int n; 2 char trophy[maxn]; 3 struct Node 4 { 5 int l,

Educational Codeforces Round 55 (Rated for Div. 2) C. Multi-Subject Competition (实现,贪心,排序)

C. Multi-Subject Competition time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output A multi-subject competition is coming! The competition has m different subjects participants can choose from. That'

Educational Codeforces Round 36 (Rated for Div. 2)

Educational Codeforces Round 36 (Rated for Div. 2) F. Imbalance Value of a Tree You are given a tree T consisting of n vertices. A number is written on each vertex; the number written on vertex i is ai. Let's denote the function I(x,?y) as the differ