1. 程式人生 > >Codeforces Round #375 (Div. 2)

Codeforces Round #375 (Div. 2)

eve find names eps push_back include std truct pla

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

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)