• Codeforces Round #375 (Div. 2)


    昨天打的,补了一天半才补完。。。

    A:水题

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=50000+10,maxn=2000+10,inf=0x3f3f3f3f;
    
    int main()
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        int ans=10000;
        for(int i=1;i<=100;i++)
        {
            ans=min(ans,abs(i-a)+abs(i-b)+abs(i-c));
        }
        printf("%d
    ",ans);
        return 0;
    }
    /********************
    
    ********************/
    A

    B:也很水,模拟即可

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=50000+10,maxn=2000+10,inf=0x3f3f3f3f;
    
    vector<string>in,out;
    int main()
    {
        fio;
        int n;
        string s;
        cin>>n>>s;
        bool inside=0;
        string te="";
        for(int i=0;i<n;i++)
        {
            if(s[i]=='(')
            {
                if(te!="")out.pb(te);
                te="";
                inside=1;
            }
            else if(s[i]==')')
            {
                if(te!="")in.pb(te);
                te="";
                inside=0;
            }
            else if(s[i]!='_')te+=s[i];
            else
            {
                if(inside)in.pb(te);
                else out.pb(te);
                te="";
            }
        }
        if(te!="")
        {
            if(inside)in.pb(te);
            else out.pb(te);
        }
        int maxx=0;
        for(int i=0;i<out.size();i++)
            maxx=max(maxx,(int)out[i].size());
        int num=0;
        for(int i=0;i<in.size();i++)
            if(in[i]!="")
                num++;
        cout<<maxx<<" "<<num<<"
    ";
        return 0;
    }
    /********************
    
    ********************/
    B

    C:题意:给一些n个数,要改变最小的次数来使得1到m出现最少的次数最大

    题解:肯定n/m就是次数,然后依次找需要改变的地方填充即可

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=4000+10,maxn=2000+10,inf=0x3f3f3f3f;
    
    int a[N];
    int num[N];
    bool ok[N];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]<=m)num[a[i]]++;
        }
        int ans1=n/m,ans2=0;
        for(int i=1;i<=m;i++)
        {
            int te=min(ans1,num[i]);
            for(int j=0;j<n;j++)
            {
                if(!ok[j]&&a[j]==i&&te)
                {
                    ok[j]=1;
                    te--;
                }
            }
        }
      //  for(int i=0;i<n;i++)printf("%d
    ",ok[i]);
        stack<pii>s;
        for(int i=1;i<=m;i++)
        {
            if(num[i]<ans1)
            {
                ans2+=ans1-num[i];
                s.push(mp(i,ans1-num[i]));
            }
        }
        printf("%d %d
    ",ans1,ans2);
        for(int i=0;i<n;i++)
        {
            if(!ok[i])
            {
                if(!s.empty())
                {
                    a[i]=s.top().fi;
                    s.top().se--;
                    if(s.top().se==0)s.pop();
                }
            }
            printf("%d ",a[i]);
        }
        puts("");
        return 0;
    }
    /********************
    
    ********************/
    C

    D:傻逼题,爆搜即可(当时爆搜写爆了,然后mle。。。。原来递归太深也是会mle的)

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=100+10,maxn=2500+10,inf=0x3f3f3f3f;
    
    int n,m,k;
    char ma[N][N];
    bool vis[N][N];
    struct lake{
        int x,y,water;
        bool operator <(const lake& rhm)const{
            return water<rhm.water;
        }
    }a[maxn];
    int num;
    void dfs(int x,int y)
    {
        if(x<0||x>=n||y<0||y>=m||vis[x][y]||ma[x][y]=='*')return ;
        if(x==0||x==n-1||y==0||y==m-1)num=-1;
        if(num!=-1)num++;
        vis[x][y]=1;
        dfs(x+1,y);
        dfs(x-1,y);
        dfs(x,y-1);
        dfs(x,y+1);
    }
    void land(int x,int y)
    {
        if(x<0||x>=n||y<0||y>=m||ma[x][y]=='*')return ;
        ma[x][y]='*';
        land(x+1,y);
        land(x-1,y);
        land(x,y+1);
        land(x,y-1);
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<n;i++)
            scanf("%s",ma[i]);
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(ma[i][j]=='.'&&!vis[i][j])
                {
                    num=0;
                    dfs(i,j);
    //                cout<<num<<endl;
                    if(num>0)a[cnt++]={i,j,num};
                }
            }
        }
        sort(a,a+cnt);
        int ans=0;
    //    for(int i=0;i<cnt;i++)
    //    {
    //        cout<<a[i].x<<" "<<a[i].y<<" "<<a[i].water<<endl;
    //    }
        for(int i=0;i<cnt-k;i++)
        {
            ans+=a[i].water;
            land(a[i].x,a[i].y);
        }
        printf("%d
    ",ans);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
                printf("%c",ma[i][j]);
            puts("");
        }
        return 0;
    }
    /********************
    5 7 0
    *.*****
    *..****
    **..***
    **.*.**
    *******
    ********************/
    D

    E:题意:给你一张无向图,要求变成有向图,使得出度和入读相同的点最多

    题解:根据欧拉路径的定义,只有起点和终点入度和出度不相同,其他都相同,那么我们可以对图中所有奇点(含奇数条边)连到虚拟节点上,然后因为奇点个数一定为偶数,那么这张图就变成欧拉回路了,我们可以用Hierholzer 算法来求解,最后删去虚拟节点连的边就好了

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=200+10,maxn=2500+10,inf=0x3f3f3f3f;
    
    int G[N][N],cnt[N];
    int in[N],out[N];
    stack<pii>s;
    int n,m;
    void dfs(int u,int f)
    {
    //    cout<<u<<" "<<f<<endl;
        for(int i=1;i<=n+1;i++)
        {
            if(G[u][i])
            {
                G[u][i]--;
                G[i][u]--;
                dfs(i,u);
            }
        }
        if(f!=-1&&f!=n+1&&u!=n+1)
        {
            s.push(mp(f,u));
            in[u]++;
            out[f]++;
        }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            memset(in,0,sizeof in);
            memset(out,0,sizeof out);
            memset(G,0,sizeof G);
            memset(cnt,0,sizeof cnt);
            while(!s.empty())s.pop();
            for(int i=0;i<m;i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                G[a][b]++;G[b][a]++;
                cnt[a]^=1;
                cnt[b]^=1;
            }
            for(int i=1;i<=n;i++)
            {
                if(cnt[i])
                {
                    G[n+1][i]++;
                    G[i][n+1]++;
                }
            }
            dfs(n+1,-1);
            while(s.size()<m)
            {
                for(int i=1;i<=n+1;i++)
                    for(int j=1;j<=n+1;j++)
                        if(G[i][j])
                            dfs(i,-1);
            }
            int ans=0;
            for(int i=1;i<=n;i++)
                if(in[i]==out[i])
                    ans++;
            printf("%d
    ",ans);
            while(!s.empty())
            {
                printf("%d %d
    ",s.top().fi,s.top().se);
                s.pop();
            }
        }
        return 0;
    }
    /********************
    1
    6 6
    1 2
    2 3
    3 1
    4 5
    5 6
    4 6
    ********************/
    E

    F:题意:给你一张无向图,要求找到一颗生成树,使得s,t两个节点的度不超过ds,dt

    题解:刚开始想到的是先求出所有的桥,然后判断与s,t相连的桥个数有没有超过ds,dt,最后删掉多余的边就好了,但是我发现这个方法有个漏洞,就是当有两个不相交的连通图连向s或者t的时候,此时的删边操作会很复杂,所有放弃了这个做法,正解是先删掉s,t找联通块,然后联通块分成了三种,一种是只能和s连,一种是只能和t连,一种是st都能连,我们先连上前两种情况,对于第三种情况,我分了两种情况,看st有没有一条路,当st有一条路时,看,第三种联通块有几个,因为只有一个时,直接s,t连向它更优,其他的先连s,t,再连入度小的那一个,当s,t没有路时,第一个直接连s,连t,其他的连度小的那一个

    =-=代码写的复杂了,应该是可以精简一点的

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=200000+10,maxn=400000+10,inf=0x3f3f3f3f;
    
    pii p[maxn];
    int father[N],belong[N];
    vector<int>v[N],block[N];
    bool vis[N];
    int s,t,ds,dt;
    int n,m,cnt;
    int tos[N],tot[N];
    int tosis[N],totis[N];
    int Find(int x)
    {
        return x==father[x]?x:father[x]=Find(father[x]);
    }
    void dfs(int u)
    {
        if(u==s||u==t)return ;
        vis[u]=1;
        block[cnt].pb(u);
        belong[u]=cnt;
        for(int i=0;i<v[u].size();i++)
        {
            int x=v[u][i];
            if(!vis[x])dfs(x);
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            p[i]=mp(a,b);
            v[a].pb(b);v[b].pb(a);
        }
        scanf("%d%d%d%d",&s,&t,&ds,&dt);
        cnt=0;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                ++cnt,dfs(i);
                if(block[cnt].size()==0)cnt--;
            }
            father[i]=i;
        }
    //    for(int i=1;i<=cnt;i++)
    //    {
    //        for(int j=0;j<block[i].size();j++)
    //        {
    //            printf("%d ",block[i][j]);
    //            printf("++%d--",belong[block[i][j]]);
    //        }
    //        puts("");
    //    }
        vector<pii>ans;
        for(int i=0;i<m;i++)
        {
            int x=p[i].fi,y=p[i].se;
            if(belong[x]!=0&&belong[x]==belong[y])
            {
                int fx=Find(x),fy=Find(y);
                if(fx!=fy)
                {
                    father[fx]=fy;
                    ans.pb(mp(x,y));
                }
            }
            else if(belong[x]!=0&&belong[y]==0)
            {
                if(y==s)
                {
                    tos[belong[x]]++;
                    tosis[belong[x]]=x;
                }
                else
                {
                    tot[belong[x]]++;
                    totis[belong[x]]=x;
                }
            }
            else if(belong[y]!=0&&belong[x]==0)
            {
                if(x==s)
                {
                    tos[belong[y]]++;
                    tosis[belong[y]]=y;
                }
                else
                {
                    tot[belong[y]]++;
                    totis[belong[y]]=y;
                }
            }
        }
        for(int i=1;i<=cnt;i++)
        {
            if(tot[i]&&!tos[i])
            {
                int x=totis[i],y=t;
                int fx=Find(x),fy=Find(y);
                if(fx!=fy)
                {
                    father[fx]=fy;
                    ans.pb(mp(x,y));
                }
            }
            else if(!tot[i]&&tos[i])
            {
                int x=tosis[i],y=s;
                int fx=Find(x),fy=Find(y);
                if(fx!=fy)
                {
                    father[fx]=fy;
                    ans.pb(mp(x,y));
                }
            }
        }
    //    for(int i=1;i<=cnt;i++)
    //    {
    //        printf("%d %d %d %d
    ",tot[i],totis[i],tos[i],tosis[i]);
    //    }
        int des=0,det=0;
        for(int i=0;i<ans.size();i++)
        {
            int x=ans[i].fi,y=ans[i].se;
            if(x==s||y==s)des++;
            else if(x==t||y==t)det++;
        }
        if(des>ds||det>dt)return 0*puts("No");
        bool hasst=0;
    //    printf("%d++++%d
    ",s,t);
        for(int i=0;i<m;i++)
        {
    //        printf("%d %d
    ",p[i].fi,p[i].se);
            if((p[i].fi==s&&p[i].se==t)||(p[i].fi==t&&p[i].se==s))
                hasst=1;
        }
        int res=0;
        for(int i=1;i<=cnt;i++)
            if(tot[i]&&tos[i])
                res++;
        if(hasst&&res!=1)
        {
    //        puts("+++++");
            if(Find(s)!=Find(t))
            {
                father[Find(s)]=Find(t);
                ans.pb(mp(s,t));
                des++,det++;
                if(des>ds||det>dt)return 0*puts("No");
            }
            for(int i=1; i<=cnt; i++)
            {
                if(tot[i]&&tos[i])
                {
                    if(des<ds)
                    {
                        int x=tosis[i],y=s;
                        int fx=Find(x),fy=Find(y);
                        if(fx!=fy)
                        {
                            father[fx]=fy;
                            ans.pb(mp(x,y));
                        }
                        des++;
                    }
                    else if(det<dt)
                    {
                        int x=totis[i],y=t;
                        int fx=Find(x),fy=Find(t);
                        if(fx!=fy)
                        {
                            father[fx]=fy;
                            ans.pb(mp(x,y));
                        }
                        det++;
                    }
                    else return 0*puts("No");
                }
            }
        }
        else
        {
            int one=0;
            for(int i=1;i<=cnt;i++)
            {
                if(tot[i]&&tos[i])
                {
                    if(!one)
                    {
                        int x=totis[i],y=t;
                        int fx=Find(x),fy=Find(y);
                        if(fx!=fy)
                        {
                            father[fx]=fy;
                            ans.pb(mp(x,y));
                        }
                        det++;
                        x=tosis[i],y=s;
                        fx=Find(x),fy=Find(y);
                        if(fx!=fy)
                        {
                            father[fx]=fy;
                            ans.pb(mp(x,y));
                        }
                        des++;
                        if(des>ds||det>dt)return 0*puts("No");
                    }
                    else
                    {
                        if(des<ds)
                        {
                            int x=tosis[i],y=s;
                            int fx=Find(x),fy=Find(y);
                            if(fx!=fy)
                            {
                                father[fx]=fy;
                                ans.pb(mp(x,y));
                            }
                            des++;
                        }
                        else if(det<dt)
                        {
                            int x=totis[i],y=t;
                            int fx=Find(x),fy=Find(t);
                            if(fx!=fy)
                            {
                                father[fx]=fy;
                                ans.pb(mp(x,y));
                            }
                            det++;
                        }
                        else return 0*puts("No");
                    }
                    one=1;
                }
            }
        }
        puts("Yes");
    //    printf("%d
    ",ans.size());
        for(int i=0;i<ans.size();i++)
            printf("%d %d
    ",ans[i].fi,ans[i].se);
        return 0;
    }
    /********************
    10 10
    1 3
    10 3
    6 1
    2 7
    1 7
    1 9
    9 5
    2 10
    10 8
    4 3
    9 5 2 4
    ********************/
    F
  • 相关阅读:
    Silverlight Toolkit ListBoxDragDropTarget学习笔记
    函数指针和指针函数(转)
    面试题_反转链表
    C++中的异或运算符^
    面试题_旋转字符串
    面试题_寻找丑数
    模拟一个简单的基于tcp的远程关机程序
    管理指针成员
    赫夫曼树编码问题
    堆的基本操作
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/8287498.html
Copyright © 2020-2023  润新知