zoukankan      html  css  js  c++  java
  • Codeforces Round #441 (Div. 2, by Moscow Team Olympiad)

    爆炸场,A被hack两次,a,c都看错题意。。。还是太菜了

    A水题,ifelse写的太搓了被hack。。

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    
    const double g=10.0,eps=1e-7;
    const int N=500000+10,maxn=sqrt(N)+10,inf=0x3f3f3f;
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,a,b,c;
        cin>>n>>a>>b>>c;
        n--;
        if(n==0)cout<<0<<endl;
        else
        {
            if(c<=a&&c<=b)cout<<(n-1)*c+min(a,b)<<endl;
            else
            {
                cout<<n*min(a,b)<<endl;
            }
        }
        return 0;
    }
    /********************
    
    ********************/
    A

    B也是瞎搞,找间距是k的倍数,直接取模计数

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    
    const double g=10.0,eps=1e-7;
    const int N=100000+10,maxn=sqrt(N)+10,inf=0x3f3f3f;
    
    int a[N];
    map<int,int>b;
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,m,k;
        cin>>n>>k>>m;
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
            b[a[i]%m]++;
        }
        int id=-1;
        for(int i=0;i<m;i++)
        {
            if(b[i]>=k)
            {
                id=i;
                break;
            }
        }
        if(id>=0)
        {
            cout<<"Yes"<<endl;
            vector<int>v;
            for(int i=0;i<n;i++)
            {
                if(a[i]%m==id)
                    v.pb(a[i]);
            }
            for(int i=0;i<k;i++)cout<<v[i]<<" ";
            cout<<endl;
        }
        else cout<<"No"<<endl;
        return 0;
    }
    /********************
    
    ********************/
    B

    C找十进制每一位加到自身等于一个数,直接枚举1到81,用n挨个减,判断就好了

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    
    const double g=10.0,eps=1e-7;
    const int N=100000+10,maxn=sqrt(N)+10,inf=0x3f3f3f;
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n;
        cin>>n;
        vector<int>v;
        for(int i=1;i<=81;i++)
        {
            int sum=0,s=n-i;
            while(s)
            {
                sum+=s%10;
                s/=10;
            }
            if(sum==i)v.pb(n-i);
        }
        sort(v.begin(),v.end());
        cout<<v.size()<<endl;
        for(int i=0;i<v.size();i++)
            cout<<v[i]<<endl;
        return 0;
    }
    /********************
    
    ********************/
    C

    D题意:每次把第i位放一个东西,操作要求把所有的东西放到最后。解法:遍历一遍,同时维护一个最后一位输出就好了

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    
    const double g=10.0,eps=1e-7;
    const int N=300000+10,maxn=sqrt(N)+10,inf=0x3f3f3f;
    
    int s[N];
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,cnt;
        cin>>n;
        cnt=n;
        cout<<1<<"
    ";
        for(int i=1;i<=n;i++)
        {
            int a;
            cin>>a;
            s[a]++;
            if(a==cnt)
            {
                while(cnt>0&&s[cnt])cnt--;
            }
            cout<<cnt-n+i+1<<"
    ";
        }
        return 0;
    }
    /********************
    
    ********************/
    D

    E题意:有n个类似字符串a,A的东西,然后刚开始是小写,可以把某几个改成大写,要求最后结果是按字符串递增的

    题解:用一个数组维护不能改变的数,还有一个维护已经改变的数,用vector存必须同时改变的数,当需要改变时dfs容器,看有没有产生冲突,每两个字符串找第一个不相同的字符,此时只有八种情况,挨个枚举就行了,分别是(1,2)(1‘,2)(1,2’)(1‘,2’)(2,1)(2’,1)(2,1‘)(2’,1‘)

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    
    const double g=10.0,eps=1e-7;
    const int N=100000+10,maxn=sqrt(N)+10,inf=0x3f3f3f;
    
    bool ca[N],no[N],f;
    int sz[N];
    vector<int>s[N];
    vector<int>v[N];
    void dfs(int u)
    {
        if(no[u])
        {
            f=1;
            return ;
        }
        else ca[u]=1;
        for(int i=0;i<v[u].size()&&!f;i++)
        {
            dfs(v[u][i]);
        }
    }
    void fuck(int p1,int p2)
    {
        if(p1>p2)
        {
            if(!ca[p1]&&!ca[p2])
            {
                f=0;
                dfs(p1);
                if(f)
                {
                    puts("No");
                    exit(0);
                }
                else no[p2]=1;
            }
            else if(ca[p1]&&!ca[p2])
            {
                no[p2]=1;
            }
            else
            {
                puts("No");
                exit(0);
            }
        }
        else
        {
            if(!ca[p1]&&ca[p2])
            {
                f=0;
                dfs(p1);
                if(f)
                {
                    puts("No");
                    exit(0);
                }
            }
            else if(!ca[p1]&&!ca[p2])
            {
                v[p2].pb(p1);
            }
        }
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&sz[i]);
            s[i].clear();
            for(int j=0;j<sz[i];j++)
            {
                int a;
                scanf("%d",&a);
                s[i].pb(a);
            }
        }
        for(int i=2;i<=n;i++)
        {
            if(s[i]==s[i-1])continue;
            else if(sz[i-1]>sz[i])
            {
                bool ok=1;
                for(int j=0;j<s[i].size();j++)
                {
                    if(s[i-1][j]!=s[i][j])
                    {
                        fuck(s[i-1][j],s[i][j]);
                        ok=0;
                        break;
                    }
                }
                if(ok)
                {
                    puts("No");
                    return 0;
                }
            }
            else if(sz[i-1]<=sz[i])
            {
                for(int j=0;j<s[i-1].size();j++)
                {
                    if(s[i-1][j]!=s[i][j])
                    {
                        fuck(s[i-1][j],s[i][j]);
                        break;
                    }
                }
            }
        }
        puts("Yes");
        v[0].clear();
        for(int i=1;i<=m;i++)
           if(ca[i])
                v[0].pb(i);
        printf("%d
    ",v[0].size());
        for(int i=0;i<v[0].size();i++)
            printf("%d ",v[0][i]);
        puts("");
        return 0;
    }
    /********************
    
    ********************/
    E

     E还可以用2-sat做,每次遇到不同的字符就找冲突关系来建图,当遇到不同时,我们用a,b,a',b'代替,如果a<b,那么当选择a时,那么应该取a'来构成冲突,同理取b'时应该取b,如果a>b,那么选b'时只能选择a,选a时只能选择b',这样构图之后跑一边tarjan,因为tarjan拍好之后拓扑序是反的,所以输出拓扑序大的那一个,因为拓扑序大 的那一个不会有入度,不会与其他强连通分量构成冲突

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    
    const double g=10.0,eps=1e-7;
    const int N=400000+10,maxn=100000+10,inf=0x3f3f3f;
    
    int dfn[N],low[N];
    int inans[N],ins[N],ans[N];
    stack<int>s;
    int num,index,n,m;
    vector<int>v[N],p[N];
    void tarjan(int u)
    {
        ins[u]=2;
        dfn[u]=low[u]=++index;
        s.push(u);
        for(int i=0;i<v[u].size();i++)
        {
            int x=v[u][i];
            if(!dfn[x])
            {
                tarjan(x);
                low[u]=min(low[u],low[x]);
            }
            else if(ins[x]==2)low[u]=min(low[u],dfn[x]);
        }
        if(dfn[u]==low[u])
        {
            ++num;
            while(!s.empty())
            {
                int k=s.top();
                s.pop();
                ins[k]=1;
                inans[k]=num;
                if(u==k)break;
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            int a;
            scanf("%d",&a);
            p[i].clear();
            for(int j=0;j<a;j++)
            {
                int k;
                scanf("%d",&k);
                p[i].pb(k);
            }
        }
        num=index=0;
        for(int i=2;i<=n;i++)
        {
            if(p[i]==p[i-1])continue;
            if(p[i-1].size()>p[i].size())
            {
                bool ok=0;
                for(int j=0;j<p[i].size();j++)
                {
                    if(p[i-1][j]!=p[i][j])
                    {
                        int p1=p[i-1][j],p2=p[i][j];
                        if(p1>p2)
                        {
                       //     cout<<p1<<" "<<p2+m<<endl;
                       //     cout<<p2+m<<" "<<p1<<endl;
                            v[p1].pb(p1+m);
                            v[p2+m].pb(p2);
                        }
                        else
                        {
                      //      cout<<p1<<" "<<p2<<endl;
                      //      cout<<p2+m<<" "<<p1+m<<endl;
                            v[p1].pb(p2);
                            v[p2+m].pb(p1+m);
                        }
                        ok=1;
                        break;
                    }
                }
                if(!ok)
                {
                    cout<<"No"<<endl;
                    return 0;
                }
            }
            else
            {
                for(int j=0;j<p[i-1].size();j++)
                {
                    if(p[i-1][j]!=p[i][j])
                    {
                        int p1=p[i-1][j],p2=p[i][j];
                        if(p1>p2)
                        {
                       //     cout<<p1<<" "<<p2+m<<endl;
                       //     cout<<p2+m<<" "<<p1<<endl;
                            v[p1].pb(p1+m);
                            v[p2+m].pb(p2);
                        }
                        else
                        {
                      //      cout<<p1<<" "<<p2<<endl;
                       //     cout<<p2+m<<" "<<p1+m<<endl;
                            v[p1].pb(p2);
                            v[p2+m].pb(p1+m);
                        }
                        break;
                    }
                }
            }
        }
        for(int i=1;i<=2*m;i++)
            if(!dfn[i])
                tarjan(i);
        for(int i=1;i<=m;i++)
        {
            if(inans[i]==inans[i+m])
            {
                cout<<"No"<<endl;
                return 0;
            }
        }
        cout<<"Yes"<<endl;
        int res=0;
        for(int i=1;i<=m;i++)
            if(inans[i]>inans[i+m])
                res++;
        printf("%d
    ",res);
        for(int i=1;i<=m;i++)
            if(inans[i]>inans[i+m])
                printf("%d ",i);
        puts("");
        return 0;
    }
    /********************
    6 5
    2 1 2
    2 1 2
    3 1 2 3
    2 1 5
    2 4 4
    2 4 4
    ********************/
    E 2-sat

     F:题意:有一组数,找区间l,r全部或起来的值大于区间最大值的区间个数

    题解:用总数-不能取的区间,对于不能减的区间我们可以用一个l数组一个r数组来维护,l[i]代表i不能取的区间到最左端的最远距离,r同理,这样结果关于这一个点不能取的区间种数就是(i-l[i])*(r[i]-i)

    计算l数组时,我们必须要用一个map来维护,因为如果一个区间里有两个相同的值时,我们会减两次,那么用map记录每次i的位置,对l赋初值时,赋map对应的值,因为l已经排除了重复的情况,所以r不用重复的去重,直接反向算就好了

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    
    const double g=10.0,eps=1e-7;
    const int N=500000+10,maxn=10000+10,inf=0x3f3f3f;
    
    int a[N],l[N],r[N],pos[32];
    map<int,int>last;
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
        {
            l[i]=last[a[i]];
            for(int j=0;j<32;j++)
                if((a[i]&(1<<j))==0)
                    l[i]=max(l[i],pos[j]);
            for(int j=0;j<32;j++)
                if((a[i]&(1<<j))>0)
                    pos[j]=i;//最后出现的第j位是1的那个数
            last[a[i]]=i;
        }
        for(int i=0;i<32;i++)pos[i]=n+1;
        for(int i=n;i>=1;i--)
        {
            r[i]=n+1;
            for(int j=0;j<32;j++)
                if((a[i]&(1<<j))==0)
                    r[i]=min(r[i],pos[j]);
            for(int j=0;j<32;j++)
                if((a[i]&(1<<j))>0)
                    pos[j]=i;
        }
        ll ans=(ll)n*(n+1)/2;
        for(int i=1;i<=n;i++)
        {
            ll t1=i-l[i],t2=r[i]-i;
            ans-=t1*t2;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    /********************
    
    ********************/
    F
  • 相关阅读:
    #include <boost/scoped_ptr.hpp>
    #include <boost/function.hpp>
    #include <boost/bind.hpp>
    8.4散列表查找
    #include <boost/array.hpp>
    异常
    lambda
    #include <amp.h>
    #include <bitset>
    #include <hash_set>
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7684210.html
Copyright © 2011-2022 走看看