723A - The New Year: Meeting Friends

#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
    int x[3];
    scanf("%d%d%d",&x[0],&x[1],&x[2]);
    sort(x,x+3);
    printf("%d",x[2]-x[0]);
    return 0;
}

723B - Text Document Analysis

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=300;
char c[N];
int main()
{
    int n,ans1=0,ans2=0;
    scanf("%d%s",&n,c);
    for(int i=0,zt=0,sl=0,len=0;i<n;++i)
    {
        if(c[i]=='(') zt=1,sl=0,len=0;
        else if(c[i]==')') 
        {
            if(len>0) ++ans2;
            zt=len=0;
        }
        else if(c[i]=='_'&&zt) 
        {
            if(len>0) ++ans2;
            len=0;
        }
        else if(c[i]=='_') len=0;
        else if(c[i]!='_'&&!zt) ans1=max(++len,ans1);
        else ++len;
    }
    printf("%d %d",ans1,ans2);
    return 0;
}

723C - Polycarp at the Radio

#include<cstdio>
#include<vector>
using namespace std;
const int N=2005;
int a[N],to[N],wz[N],s;
int main()
{
    int n,m,yq,cs=0;
    scanf("%d%d",&n,&m);
    yq=n/m;
    for(int i=1;i<=n;++i) 
    {
        scanf("%d",&a[i]);
        if(a[i]>m||to[a[i]]>=yq) wz[++s]=i;
        else ++to[a[i]];
    }
    for(int i=1;i<=m;++i)
            while(to[i]<yq)
            {
                ++to[i];
                a[wz[s--]]=i;
                ++cs;
            }
    printf("%d %d\n",yq,cs);
    for(int i=1;i<=n;++i)
        printf("%d ",a[i]);
    return 0;
}

723D - Lakes in Berland

#include<cstdio>
#include<algorithm>
using namespace std;
char c[55][55];
int sl,bx[4]={1,-1},by[4]={0,0,1,-1},n,m;
bool vis[55][55];
struct A
{
    int a,b;
}q[2505],st[2505],dx[2505];
bool cmp(const A &t1,const A &t2)
{
    return t1.a<t2.a;
}
void drow_it(A wz)
{
    c[wz.a][wz.b]='*';
    for(int i=0;i<4;++i)
    {
        int ba=wz.a+bx[i],bb=wz.b+by[i];
        if(ba>0&&bb>0&&ba<=n&&bb<=m&&c[ba][bb]!='*') drow_it((A){ba,bb});
    }
}
int main()
{
    int k,ans=0;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;++i)
        scanf("%s",c[i]+1);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            if(c[i][j]!='*'&&!vis[i][j])
            {
                int t=0,w=1;
                bool sf=i!=1&&j!=1&&i!=n&&j!=m;
                q[0].a=i,q[0].b=j;
                vis[i][j]=1;
                for(;t<w;++t)
                    for(int o=0;o<4;++o)
                    {
                        int ba=q[t].a+bx[o],bb=q[t].b+by[o];
                        if(ba>0&&bb>0&&ba<=n&&bb<=m&&c[ba][bb]!='*'&&!vis[ba][bb])
                        {
                            vis[ba][bb]=1;
                            q[w++]=(A){ba,bb};
                            if(ba==1||bb==1||ba==n||bb==m) sf=0;
                        }
                    }
                if(sf) dx[++sl].a=w,st[dx[sl].b=sl]=(A){i,j};
            }
    sort(dx+1,dx+sl+1,cmp);
    for(int i=1;sl>k;++i,--sl) 
        ans+=dx[i].a,drow_it(st[dx[i].b]);
    printf("%d\n",ans);
    for(int i=1;i<=n;++i) printf("%s\n",c[i]+1);
    return 0;
}

723E - One-Way Reform

 题面大意:给一个n个点m条边的图,将这些双向边改为单向边,尽量使出度等于入度的点多,输出所有边的方向。

解法:

对于度为奇数的点的数量一定为偶数,编号为1,。。。,k

将1-2,3-4,。。。,k-1-k连一条边

它就变成了一个欧拉回路,因此,我们可以dfs对于图中原有的边输出经过的方向,而且入度真正等于出度的点只有度数为偶数的点。

#include<cstdio>
#include<cstring>
const int N=205;
struct X
{
    int v,n,f;
    bool vis,re;
}x[80005];
int s,d[N],j[N],v[N];
void add(int u,int v,bool re)
{
    x[++s].n=x[u].f;
    x[x[u].f=s].v=v;
    x[s].re=re;
}
void dfs(int u)
{
    v[u]=1;
    for(int i=x[u].f;i;i=x[i].n)
        if(!x[i].vis)
        {
            x[i].vis=x[i^1].vis=1;
            if(x[i].re) printf("%d %d\n",u,x[i].v);
            dfs(x[i].v);
        }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m,ct=0,ans=0;s=1;
        scanf("%d%d",&n,&m);
        memset(x,0,sizeof(x));
        memset(d,0,sizeof(d));
        memset(v,0,sizeof(v));
        for(int i=1;i<=m;++i)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            add(u,v,1),add(v,u,1);
            ++d[u];++d[v];
        }
        for(int i=1;i<=n;++i)
            if(d[i]&1) j[++ct]=i;
            else ++ans;
        printf("%d\n",ans);
        for(int i=1;i<ct;i+=2)
            add(j[i],j[i+1],0),add(j[i+1],j[i],0);
        for(int i=1;i<=n;++i)
            if(!v[i]) dfs(i);
    }
    return 0;
}

723F - st-Spanning Tree

题目大意:给你一个无向图,让你生成一棵树,这棵树中点s和t的度数分别小于ds,dt,问是否能够生成,如果能,则需要输出它所包含的边

首先对于那些端点不是s,t的边,并且用并查集(其实也就是类似克鲁斯卡尔中的方法)来避免边过多。

然后对于已经被连起来的点,我们把它们看成一个点,我们把这些点分成四类1.有边与s连  2.有边与t连  3.有边于s和t连 4.与s,t都没有连边

当有第四种情况就可以直接判断no了,1直接与s连接并且一定消耗1个s的度数,1直接与t连接并且一定消耗1个t的度数,然后之后再对第3种点分配给s或者t。

度数一旦不够就判断为no

最后的问题就是如何把s和t连接起来。如果有第三种点那么就直接借助其中一个点间接连接s和t。

如果没有第三种点,那么只能用能把s和t直接连接的边进行连接了。

#include<cstdio>
#include<cstdlib>
const int N=200005;
struct X{
    int u,v;
    bool bj;
}x[N<<1];
int fa[N],ans[N],sl,ts,jl[4],sf[N][2];
int fi(int a){
    int b=a,c;
    while(fa[b]) b=fa[b];
    while(fa[a]){
        c=fa[a];
        fa[a]=b;
        a=c;
    }
    return a;
}
int main(){
    int n,m,s[2],d[2];
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i) scanf("%d%d",&x[i].u,&x[i].v);
    scanf("%d%d%d%d",&s[0],&s[1],&d[0],&d[1]);
    for(int i=1;i<=m;++i)
        if(x[i].u!=s[0]&&x[i].u!=s[1]&&x[i].v!=s[0]&&x[i].v!=s[1]){
            if(fi(x[i].u)!=fi(x[i].v)){
                fa[fi(x[i].u)]=fi(x[i].v);
                ans[++sl]=i;
            }
        }
        else x[i].bj=1;
    for(int i=1;i<=m;++i)
        if(x[i].bj){
            int t=x[i].u-s[0]&&x[i].u-s[1]?x[i].u:x[i].v;
            if(t-s[0]&&t-s[1]) sf[fi(t)][x[i].u+x[i].v==s[1]+t]=i;
            else ts=i;
        }
    for(int i=1;i<=n;++i)
        if(fi(i)==i&&i-s[0]&&i-s[1])
            if(sf[i][0]&&sf[i][1]) ++jl[3];
            else if(sf[i][0]) --d[0],ans[++sl]=sf[i][0];
            else if(sf[i][1]) --d[1],ans[++sl]=sf[i][1];
            else return 0;
    if(d[0]<=0||d[1]<=0||d[0]+d[1]<=jl[3]||(!ts&&!jl[3])){
        printf("No");
        return 0;
    }
    printf("Yes\n");
    if(!jl[3]) ans[++sl]=ts;
    for(int i=1,pd=0;i<=n;++i)
        if(fi(i)==i&&i-s[0]&&i-s[1]&&sf[i][0]&&sf[i][1]){
            if(d[0]){
                --d[0];
                ans[++sl]=sf[i][0];
                if(!pd) ans[++sl]=sf[i][1],pd=1;
            }
            else ans[++sl]=sf[i][1];
        }
    for(int i=1;i<n;++i) printf("%d %d\n",x[ans[i]].u,x[ans[i]].v);
    return 0;
}