Helvetic Coding Contest 2019

Posted fengxunling

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Helvetic Coding Contest 2019相关的知识,希望对你有一定的参考价值。

题目链接:戳我

小注:其中部分(大括号不换行的)代码是BLUESKY007神仙写的。
小注2:如果可以的话,B2,C2,E3明天更。

CF1184 A1

直接枚举,以根号的时间复杂度判断即可。注意x,y都是正整数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 100010
#define ll long long
using namespace std;
ll r;
inline ll calc(ll x)

    ll cur=r-x*x-x-1;
    if(cur<=0) return -1;
    if(cur%(2*x)==0) return cur/(2*x);
    else return -1;

int main()

    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%lld",&r);
    for(ll i=1;i<=1000000;i++)
    
        if(calc(i)>0) 
        
            printf("%lld %lld\n",i,calc(i));
            return 0;
        
    
    printf("NO\n");
    return 0;

CF1184 A2

我们可以知道对于k,如果\(gcd(k,n)\)可以的话,那么k一定也可以。
所以我们就把枚举k才能计算的东西降低到了log的时间复杂度。
然后按每次长度为k在环上往后跳,直到跳到一个点第二次。在这期间,显然其中为1的边的个数为偶数才是可行方案。
那么直接把它们异或起来就行了。QAQ

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 200010
using namespace std;
int n,ans;
int cnt[MAXN],done[MAXN];
char s[MAXN];
int main()

    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    scanf("%s",s);
    for(int i=1;i<=n;i++) cnt[__gcd(i,n)]++;
    for(int i=1;i<=n;i++)
    
        if(cnt[i])
        
            bool flag=false;
            memset(done,0,sizeof(done));
            for(int j=0;j<n;j++)
            
                if(!done[j])
                
                    int cur_ans=0,x=j;
                    while(!done[x])
                    
                        cur_ans^=(s[x]-'0');
                        done[x]=1;
                        x=(x+i)%n;
                    
                    if(cur_ans) flag=true;
                
            
            if(!flag) ans+=cnt[i];
        
    
    printf("%d\n",ans);
    return 0;

CF1184 B1

二分。

#include<bits/stdc++.h>
 
using namespace std;
 
const int N=1e5+5;
 
struct base
    int d,g,id;
    bool operator<(const base&rhs)const
        return d!=rhs.d?d<rhs.d:id<rhs.id;
    
ba[N];
 
int s,b,a[N];
 
long long sum[N];
 
int bs(int l,int r,int u)
    if(l==r)
        return l;
    
    int mid=(l+r+1)>>1;
    if(ba[mid].d<=u)
        return bs(mid,r,u);
    
    else
        return bs(l,mid-1,u);
    

 
int main()
    scanf("%d%d",&s,&b);
    for(int i=1;i<=s;i++)
        scanf("%d",&a[i]);
    
    for(int i=1;i<=b;i++)
        scanf("%d%d",&ba[i].d,&ba[i].g);
        ba[i].id=i;
    
    sort(ba+1,ba+b+1);
    for(int i=1;i<=b;i++)
        sum[i]=sum[i-1]+ba[i].g;
    
    for(int i=1;i<=s;i++)
        printf("%lld%c",sum[bs(0,b,a[i])]," \n"[i==s]);
    
    return 0;

CF1184 B2

CF1184 C1

暴力地找四个点,然后判断一下他们构成的矩形上是不是正好缺少一个点qwq

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 100010
using namespace std;
int n;
struct Nodeint x,y;node[MAXN];
inline void calc(int a,int b,int c,int d)

    int down=0x3f3f3f3f,up=0,ll=0x3f3f3f3f,rr=0,cnt=0;
    ll=min(ll,node[a].x),ll=min(ll,node[b].x),ll=min(ll,node[c].x),ll=min(ll,node[d].x);
    rr=max(rr,node[a].x),rr=max(rr,node[b].x),rr=max(rr,node[c].x),rr=max(rr,node[d].x);
    down=min(down,node[a].y),down=min(down,node[b].y),down=min(down,node[c].y),down=min(down,node[d].y);
    up=max(up,node[a].y),up=max(up,node[b].y),up=max(up,node[c].y),up=max(up,node[d].y);
    int kkk;
    for(int i=1;i<=n;i++)
    
        if(ll<=node[i].x&&node[i].x<=rr&&(node[i].y==down||node[i].y==up)) cnt++;
        else if(down<=node[i].y&&node[i].y<=up&&(node[i].x==ll||node[i].x==rr)) cnt++;
        else kkk=i;
    
    if(cnt==n-1) 
    
        printf("%d %d\n",node[kkk].x,node[kkk].y);
        exit(0);
    

int main()

    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=4*n+1;i++)
    
        scanf("%d%d",&node[i].x,&node[i].y);
    
    n=4*n+1;
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            for(int k=j+1;k<=n;k++)
                for(int p=k+1;p<=n;p++)
                    calc(i,j,k,p);
    return 0;

CF1184 C2

CF1184 D1

开始还以为要用链表直接模拟即可,注意判断一下加入和删除的位置和当前主人公所在位置的大小。


 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 100010
#define ll long long
using namespace std;
int n,m,k,t;
int main()

    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d%d%d",&n,&k,&m,&t);
    while(t--)
    
        int op,pos;
        scanf("%d%d",&op,&pos);
        if(op==0)
        
            if(pos>=k) n=pos;
            else n-=pos,k-=pos;
        
        else
        
            if(pos<=k) k++,n++;
            else n++;
        
        printf("%d %d\n",n,k);
    
    return 0;

CF1184 E1

二分一下桥1的值,看看能否在最小生成树中。

#include<bits/stdc++.h>
 
using namespace std;
 
const int N=1e6+6;
 
int n,m,fr[N],to[N],w[N],fa[N],siz[N];
 
bool usd[N];
 
int find(int u)
    return fa[u]==u?fa[u]:fa[u]=find(fa[u]);

 
struct edge
    int u,v,w,id;
    bool operator<(const edge&rhs)const
        return w<rhs.w;
    
e[N];
 
bool unifa(int u,int v)
    if(find(u)==find(v))
        return 0;
    
    fa[find(v)]=find(u);
    return 1;

 
bool can(int u)
    for(int i=1;i<=n;i++)
        fa[i]=i;
    
    for(int i=2;i<=m;i++)
        if(e[i].w<u)
            unifa(e[i].u,e[i].v);
        
    
    return unifa(e[1].u,e[1].v);

 
int bs(int l,int r)
    if(l==r)
        return l;
    
    int mid=(l+r+1)>>1;
    if(!can(mid))
        return bs(l,mid-1);
    
    else
        return bs(mid,r);
    

 
int main()
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
        e[i].id=i;
    
    printf("%d\n",bs(0,1e9));
    return 0;

CF1184 E2

我们先构建最小生成树,然后每次处理到一条不在最小生成树上的边的时候,倍增往上面找最小的一条边的值就行了。

#include<bits/stdc++.h>
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
#define debug printf("%d %s\n",__LINE__,__FUNCTION__)
 
using namespace std;
 
const int N=1e6+6;
 
int n,m,fa[N],dep[N];
 
vector<int>G[N],W[N];
 
bool vis[N];int ans[N];
 
int find(int u)
    return fa[u]==u?fa[u]:fa[u]=find(fa[u]);

 
bool unifa(int u,int v)
    if(find(u)==find(v))
        return 0;
    
    fa[find(v)]=find(u);
    return 1;

 
struct edge
    int u,v,w,id;
    edge(int ru=0,int rv=0,int rw=0,int ri=0)
        u=ru;v=rv;w=rw;id=ri;
    
    bool operator<(const edge&rhs)const
        return w<rhs.w;
    
e[N];
 
void addedge(int u,int v,int w)
    G[u].push_back(v);W[u].push_back(w);

 
int jump[N][18],mx[N][18];
 
void dfs(int u,int fr)
    for(int i=0,v;i<(int)G[u].size();i++)
        v=G[u][i];
        if(v==fr)
            continue;
        
        dep[v]=dep[u]+1;
        jump[v][0]=u;
        mx[v][0]=W[u][i];
        for(int j=1;j<18;j++)
            jump[v][j]=jump[jump[v][j-1]][j-1];
            mx[v][j]=max(mx[v][j-1],mx[jump[v][j-1]][j-1]);
        
        dfs(v,u);
    

 
pii lca(int u,int v)
    int rep=0;
    if(dep[u]<dep[v])
        swap(u,v);
    
    for(int i=17;~i;i--)
        if(dep[jump[u][i]]>=dep[v])
            rep=max(mx[u][i],rep);
            u=jump[u][i];
        
    
    if(u==v)
        return mk(u,rep);
    
    for(int i=17;~i;i--)
        if(jump[u][i]!=jump[v][i])
            rep=max(rep,max(mx[u][i],mx[v][i]));
            u=jump[u][i];
            v=jump[v][i];
        
    
    rep=max(rep,max(mx[u][0],mx[v][0]));
    return mk(jump[u][0],rep);

 
int query(int u,int v)
    return lca(u,v).se;

 
int main()
    scanf("%d%d",&n,&m);
    for(int i=1,u,v,w;i<=m;i++)
        scanf("%d%d%d",&u,&v,&w);
        e[i]=edge(u,v,w,i);
    
    for(int i=1;i<=n;i++)
        fa[i]=i;
    
    sort(e+1,e+m+1);
    for(int i=1;i<=m;i++)
        if(unifa(e[i].u,e[i].v))
            vis[e[i].id]=1;
            addedge(e[i].u,e[i].v,e[i].w);
            addedge(e[i].v,e[i].u,e[i].w);
        
    
    dep[1]=1;dfs(1,0);
    for(int i=1;i<=m;i++)
        if(!vis[e[i].id])
            ans[e[i].id]=query(e[i].u,e[i].v);
        
    
    for(int i=1;i<=m;i++)
        if(!vis[i])
            printf("%d\n",ans[i]);
        
    
    return 0;

CF1184 E3

以上是关于Helvetic Coding Contest 2019的主要内容,如果未能解决你的问题,请参考以下文章

nowcoder 207G - Coding Contest - [最小费用最大流]

HDU5988 - 2016icpc青岛 - G - Coding Contest 费用流(利用对数化乘为加

Coding Contest HDU - 5988

Coding Contest HDU - 5988(费用流)

2016ACM/ICPC亚洲区青岛站 Coding Contest 费用流

HDU 5988 Coding Contest(费用流+浮点数)