其他分享
首页 > 其他分享> > CSU-ACM2019暑假训练(2)

CSU-ACM2019暑假训练(2)

作者:互联网

补题

原CF 1141F Graph Without Long Directed Paths

基本思路

染色问题,u和v记录边的两个顶点,dfs遍历。
有个问题是若边数=顶点数,为什么不能直接输出-1?

#include<bits/stdc++.h>
using namespace std;
typedef struct{
    vector<int>connect;
}NODE;NODE nodes[200020];
int arr[200020];
int u[200020],v[200020];
int n,m;
bool flag=true;

void dfs(int now,int pre,int precolor)
{
    arr[now]=!precolor;
    if(flag)
    {
        for(int i=0;i<nodes[now].connect.size();i++)
        {//遍历边 
            if(nodes[now].connect[i]==pre) continue;
            if(arr[nodes[now].connect[i]]==-1)
            {
                dfs(nodes[now].connect[i],now,arr[now]);
            }
            if(arr[nodes[now].connect[i]]==arr[now])
            {
                flag=false;
                return ;
            }
        }
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        arr[i]=-1;
    for(int i=1;i<=m;i++)
    {
        cin>>u[i]>>v[i];
        nodes[u[i]].connect.push_back(v[i]);
        nodes[v[i]].connect.push_back(u[i]);
    }

    dfs(1,-1,0);
    if(!flag)
    {
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=1;i<=m;i++)
        cout<<(arr[u[i]]==1?1:0);
    return 0;
}

原CF 1138B Circus

基本思路

若使用排列组合,会爆tle,因为maxn=5000,设A=(0,0)的个数,B=(0,1)的个数,C=(1,0)的个数,D=(1,1)的个数,则有
\[ \begin{array}{l} A+B+C+D=n/2 \\ C+D=B.size()+D.size()-B-D \end{array} \]
四个未知数+两个方程组,复杂度为O(N^2),注意此题卡常,三重循环爆tle。
排列的一发tle

#include<bits/stdc++.h>
using namespace std;
typedef struct{
    int a,c;
}NODE; NODE nodes[6000];
int arr[6000];
int n;bool flag=false;
void dfs(int pos,int cnt1,int cnt2,int sum1,int sum2)
{
    if(flag)return ;
    if(cnt1==cnt2&&cnt1==n/2)
    {
        if(sum1==sum2)
        {
            for(int i=0;i<n;i++)
                if(arr[i]==1)cout<<i+1<<" ";
            flag=true;
            cout<<endl;
            return ;
        }
    }
    if(cnt1<n/2)
    {
        arr[pos]=1;
        sum1+=nodes[pos].a;
        dfs(pos+1,cnt1+1,cnt2,sum1,sum2) ;
        arr[pos]=0;
    }
    if(cnt2<n/2)
    {
        sum2+=nodes[pos].c;
        dfs(pos+1,cnt1,cnt2+1,sum1,sum2);
    }
    
} 
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        char ch;cin>>ch;if(ch=='\n')cin>>ch;
        nodes[i].a=ch-'0';
    }
    for(int i=0;i<n;i++)
    {
        char ch;cin>>ch;if(ch=='\n')cin>>ch;
        nodes[i].c=ch-'0';
    }
    dfs(0,0,0,0,0);
    if(!flag)
        cout<<-1<<endl;
    return 0;
}

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef struct{
    int a,c;
}NODE; NODE nodes[6000];
int arr[6000],sum1,sum2;
vector<int>a,b,c,d;
int n;bool flag=false;
void print(int i,int j ,int k,int h)
{
    for(int x=0;x<i;x++)
    {
        cout<<a[x]<<" ";
    }
    for(int x=0;x<j;x++)
    {
        cout<<b[x]<<" ";
    }
    for(int x=0;x<k;x++)
    {
        cout<<c[x]<<" ";
    }
    for(int x=0;x<h&&x<d.size();x++)
    {
        cout<<d[x]<<" ";
    }
}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        char ch;cin>>ch;if(ch=='\n')cin>>ch;
        nodes[i].a=ch-'0';
    }
    for(int i=0;i<n;i++)
    {
        char ch;cin>>ch;if(ch=='\n')cin>>ch;
        nodes[i].c=ch-'0';
    }
    for(int i=0;i<n;i++)
    {
        if(nodes[i].a==0)
        {
            if(nodes[i].c==0)
                a.push_back(i+1);
                else b.push_back(i+1);
        }
        else
            if(nodes[i].c==0)
                c.push_back(i+1);
            else d.push_back(i+1);
    }
    for(int i=0;i<=a.size();i++)
    {
        if(flag)break;
        for(int j=0;j<=b.size();j++)
        {
            if(flag)break;

            int k=n-2*i-j-b.size()-d.size();
            int h=b.size()+d.size()-n/2+i;
            if (h<0||h>d.size()||k<0||k>c.size()||(i+j+k+h)!=n/2)continue;
            sum1=k+h;sum2=b.size()+d.size()-j-h;
            if(sum1==sum2)
            {
                print(i,j,k,h);
                flag=true;
            }
        }
    }
    if(!flag)cout<<-1<<endl;
    return 0;
}

原CF 1152B

基本思路

位操作 \(full=2^{\log{2}{x}+1}-1\),取最前的一位0,做异或运算,每做一次操作判断是否满足条件

#include<bits/stdc++.h>
using namespace std;
int x,xx,maxbit,op=0;
vector<int>q;
int main()
{
    cin>>x;xx=x;
    int t=40;
    int full=(1<<((int)log2(x)+1))-1;
    while(t--)
    {
        maxbit=0;
        int step=0;
        if(xx==full)break;
        while(x>1)
        {
            step++;
            if((x&1)==0) maxbit=step;
            x=x>>1;
        }
        op++;
        q.push_back(maxbit);
        int y=(1<<maxbit)-1;
        xx=xx^y;
        x=xx;
        if(xx==full)break;
        while(x>1)
        {
            step++;
            if((x&1)==0) maxbit=step;
            x=x>>1;
        }
        op++;
        xx=xx+1;
        x=xx;
    }
    cout<<op<<endl;
    for(int i=0;i<q.size();i++)
        cout<<q[i]<<" ";
        
    return 0;
}

标签:NODE,ch,int,ACM2019,flag,暑假,CSU,nodes,size
来源: https://www.cnblogs.com/tldr/p/11226318.html