zoukankan      html  css  js  c++  java
  • Codeforce Round #545(Div2) (BCD题解)

    B:

      给出n个元素,每个元素有两个属性(每个属性的取值为0或1),(n为偶数),即:一共有四种数对(0,0),(0,1),(1,0),(1,1)

      要求把n个元素分为2组,要求第一组的属性二的1的数量和第二组的属性二的1的数量相等( 设两组分别为A,B,满足即SUM(A.first==1)=SUM(B.second==1)

      ,求分组方案

      题解:

      一开始想用贪心来做,后来发现分情况分得不清楚了,然后看了下题解,发现题解是根据每组每种数对的数量的等量关系进行列方程,两个方程四个未知数,数据范围是(n<=5000),所以可用O(n^2)暴力枚举两个值然后求解

      代码如下:  

     1 #include<bits/stdc++.h>
     2 #define pii pair<int,int>
     3 using namespace std;
     4 const int maxn=5e3+5;
     5 struct node
     6 {
     7     int id,first,second;
     8 }art[maxn];
     9 int n;
    10 map<pii,int>m;
    11 bool cmp(node a,node b)
    12 {
    13     int sa=a.first+a.second,sb=b.first+b.second;
    14     if(sa==1 && sb==1) return a.first<b.first;
    15     return sa<sb;
    16 }
    17 int main()
    18 {
    19     cin>>n;string t,tt;cin>>t>>tt;
    20     m[{0,1}]=0,m[{1,1}]=0,m[{1,0}]=0,m[{0,0}]=0;
    21     for(int i=1;i<=n;++i)
    22     {
    23         art[i].first=t[i-1]-'0';
    24         art[i].second=tt[i-1]-'0';
    25         ++m[{art[i].first,art[i].second}];
    26         art[i].id=i;
    27     }
    28     sort(art+1,art+1+n,cmp);
    29     //cout<<endl;
    30     static int s00,s11,s01,s10; s00=s11=s01=s10=-1;
    31     for(int i=1;i<=n;++i)
    32     {
    33         if(s00<0 && art[i].first==0 && art[i].second==0) s00=i;
    34         if(s01<0 && art[i].first==0 && art[i].second==1) s01=i;
    35         if(s10<0 && art[i].first==1 && art[i].second==0) s10=i;
    36         if(s11<0 && art[i].first==1 && art[i].second==1) s11=i;
    37     }
    38     int na=m[{0,0}],nb=m[{0,1}],nc=m[{1,0}],nd=m[{1,1}];
    39     /*
    40     for(int a=0;a<=na;++a)
    41     {
    42         for(int d=0;d<=nd;++d)
    43         {
    44             if(a-d==n/2-nd-nb)
    45             {
    46                 int b=(nb+nd-2*d)/2;      //最开始的时候枚举a,d求b,c   但是这里会出现一个问题,就是b=(......)/2,如果(......)是奇数,机会出现错误,所以换了枚举方式
    47                 int c=n/2-a-b-d;
    48                 if(b<0 || c<0 || b>nb || c>nc) continue;
    49                 if(a)for(int i=s00,j=1;j<=a;++j,++i) cout<<art[i].id<<" ";
    50                 if(b)for(int i=s01,j=1;j<=b;++j,++i) cout<<art[i].id<<" ";
    51                 if(c)for(int i=s10,j=1;j<=c;++j,++i) cout<<art[i].id<<" ";
    52                 if(d)for(int i=s11,j=1;j<=d;++j,++i) cout<<art[i].id<<" ";
    53                 return 0;
    54             }
    55         }
    56     }*/
    57     for(int b=0;b<=nb;++b)
    58     {
    59         for(int d=0;d<=nd;++d)
    60         {
    61             int c=nb+nd-b-2*d;
    62             int a=n/2-b-c-d;    //先把a,c算出来,再带入式子看看对不对,注意带进去的式子,不能是恒等式,如果是恒等式,肯定是错的(原因不赘述)
    63                                 //其实不能说是错的,不过因为是恒等式所以肯定求不出来
    64             if(a-d==n/2-nb-nd)
    65             {
    66                 if(a<0 || c<0 || a>na || c>nc) continue;
    67                 if(a)for(int i=s00,j=1;j<=a;++j,++i) cout<<art[i].id<<" ";
    68                 if(b)for(int i=s01,j=1;j<=b;++j,++i) cout<<art[i].id<<" ";
    69                 if(c)for(int i=s10,j=1;j<=c;++j,++i) cout<<art[i].id<<" ";
    70                 if(d)for(int i=s11,j=1;j<=d;++j,++i) cout<<art[i].id<<" ";
    71                 return 0;
    72             }
    73         }
    74     }
    75     cout<<-1;return 0;
    76 }

      C:

      坐标离散化,复习一下lower_bound和unique(可能因为我很菜233333)

      代码如下:

      

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e3+5;
    int plat[maxn][maxn];
    int row[maxn][maxn];
    int col[maxn][maxn];
    int row_end[maxn],col_end[maxn];
    int n,m;
    
    int main()
    {
        ios::sync_with_stdio(0);
        cin>>n>>m;
        for(int i=0;i<n;++i)
        {
            for(int j=0;j<m;++j)
            {
                cin>>plat[i][j];
                row[i][j]=plat[i][j];
                col[j][i]=plat[i][j];
            }
        }
        for(int i=0;i<n;++i)
        {
            sort(row[i],row[i]+m);
            row_end[i]=unique(row[i],row[i]+m)-row[i];
        }
        for(int j=0;j<m;++j)
        {
            sort(col[j],col[j]+n);
            col_end[j]=unique(col[j],col[j]+n)-col[j];
        }
        for(int i=0;i<n;++i)
        {
            for(int j=0;j<m;++j)
            {
                int x=lower_bound(row[i],row[i]+row_end[i],plat[i][j])-row[i];
                int y=lower_bound(col[j],col[j]+col_end[j],plat[i][j])-col[j];
                cout<<max(x,y)+max(row_end[i]-x,col_end[j]-y)<<" ";
            }
            cout<<endl;
        }
        return 0;
    }

      D:

        给定两个01串,s和t,求对s进行重排使得t在s中出现的次数最多

        可用kmp或者hash来做(hash还没填坑emmm).学习了kmp,

        题解:

        可知构造的新的s'满足如下条件:把由t求出来的next数组进行无线延长,使len(t)以后的next数组是一直严格递增的,直到0的数量或者1的数量为0为止,输出剩下的0或1

        代码如下:

        

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=5e5+5;
     4 char s[maxn],t[maxn];
     5 int nex[maxn];
     6 int s1,s0,t1,t0;
     7 void getnext(char *p)
     8 {
     9     int i=0,j=-1;
    10     nex[0]=-1;
    11     int len=strlen(p);
    12     printf("%s",p);
    13     while(i<len)//构造next数组
    14     {
    15         if(j==-1 || p[i]==p[j])
    16         {
    17             nex[++i]=++j;
    18         }
    19         else j=nex[j];
    20     }
    21     s1-=t1,s0-=t0;
    22     while(s1 && s0)//当s中1和0有剩余的时候,保持next数组增长
    23     {
    24         p[i]='0';
    25         if(p[i]==p[j]&&p[i]=='0')
    26         {
    27             putchar('0');
    28             nex[++i]=++j;
    29             --s0;
    30         }
    31         else
    32         {
    33             putchar('1');
    34             p[i]='1';
    35             nex[++i]=++j;
    36             --s1;
    37         }
    38     }
    39     //输出剩余的0和1
    40     for(int q=1;q<=s1;++q) putchar('1');
    41     for(int q=1;q<=s0;++q) putchar('0');
    42 }
    43 int main()
    44 {
    45     scanf("%s%s",s,t);
    46     int lens=strlen(s),lent=strlen(t);
    47     for(int i=0;i<lens;++i) {
    48         if(s[i]=='0') ++s0;
    49         else ++s1;
    50     }
    51     for(int i=0;i<lent;++i) {
    52         if(t[i]=='0') ++t0;
    53         else ++t1;
    54     }
    55     if(s1<t1 || s0<t0){puts(s); return 0;}
    56     getnext(t);
    57 }
  • 相关阅读:
    四则运算2
    四则运算1
    学习进度条
    Mat数据结构
    Markdown语法
    C++继承和派生
    C++智能指针
    clion配置ROS
    视觉十四讲:第六讲_g2o图优化
    视觉十四讲:第六讲_ceres非线性优化
  • 原文地址:https://www.cnblogs.com/codeoosacm/p/10678922.html
Copyright © 2011-2022 走看看