Codeforces Round #375 (Div. 2)

Posted walfy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",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<<"\n";
    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\n",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\n",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\n",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\n",ans);
        while(!s.empty())
        {
            printf("%d %d\n",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\n",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\n",s,t);
    for(int i=0;i<m;i++)
    {
//        printf("%d %d\n",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\n",ans.size());
    for(int i=0;i<ans.size();i++)
        printf("%d %d\n",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

 

以上是关于Codeforces Round #375 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #375 (Div. 2) A

Codeforces Round #375 (Div. 2)

Codeforces Round #375 (Div. 2) C

Codeforces Round #375 (Div. 2)

Codeforces Round #375 (Div. 2) ABCDE

Circling Round Treasures(codeforces 375c)