zoukankan      html  css  js  c++  java
  • Codeforces Round #558 (Div. 2)

    A

    签到,然而手残WA了一发,不过加上50分名次不变。

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    int main()
    {
        scanf("%d%d",&n,&m);
        m=n-m;
        if(m==n)printf("1");
        else if(m<=n/2)printf("%d",m);
        else printf("%d",n-m);
    }
    View Code

    B

    设前i个位置存在m种颜色,显然只有以下几种情况:1、所有颜色出现1次。2、出现最多的颜色有1种,出现次多的颜色出现次数为出现最多颜色出现次数-1,且有(m-1)种。3、出现最多的颜色种类有(m-1)种,且剩余一种颜色仅出现1次。然后维护mx的值,即为出现最多颜色出现次数,随便判一下就好了。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+7;
    int n,m,ans,mx,a[N],b[N],c[N];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
        {
            int col=a[i];
            if(b[col])c[b[col]]--;else m++;
            c[++b[col]]++;
            if(b[col]>mx)mx=b[col];
            if(m==1||mx==1||c[mx]==m-1&&c[1]==1||c[mx-1]==m-1&&c[mx]==1)ans=i;
        }
        printf("%d",ans);
    }
    View Code

    C

    可以O(n^2)枚举两两点对间的直线,记录k和b,即y=kx+b,对于不存在斜率的线,记录x坐标的位置即可。eps设为1e-10即可。然后去重,统计相同斜率的直线个数直接计算。因为答案就是斜率不同的直线对数目÷2。

    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const int N=1010;
    struct line{double k,b;}l[N*N];
    int n,num,n1,n2,m,x[N],y[N],h1[N*N],h2[N*N],b[N];
    ll ans;
    bool cmp(line a,line b){return fabs(a.k-b.k)<1e-10?a.b<b.b:a.k<b.k;}
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)cin>>x[i]>>y[i];
        for(int i=1;i<n;i++)
        for(int j=i+1;j<=n;j++)
        if(x[i]==x[j])
        {
            if(!h1[x[i]+10000])n1++;
            h1[x[i]+10000]=1;
        }
        else l[++m].k=1.0*(y[i]-y[j])/(x[i]-x[j]),l[m].b=y[i]-l[m].k*x[i];
        sort(l+1,l+m+1,cmp);
        l[0].k=-1e18;
        for(int i=1;i<=m;i++)
        if(fabs(l[i].k-l[i-1].k)>1e-10)n2++,h2[++num]++;
        else if(fabs(l[i].b-l[i-1].b)>1e-10)n2++,h2[num]++;
        ans=1ll*n1*n2;
        for(int i=1;i<=num;i++)ans+=1ll*(n1+n2-h2[i])*h2[i];
        cout<<ans/2;
    }
    View Code

    D

    看到|c|<=1000,|s|,|t|<=50,不妨想到dp,f[i][j][k]表示c串走i步,到达|s|串j位置,|t|串k位置最大值为多少,若遇到字母直接转移,遇到*枚举26个字母。预处理s和t在每一个位置使用26个字母转移后的j/k最大值,这个暴力计算即可。复杂度O(|s|^3+|t|^3+26|c||s||t|)

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1002;
    int n,ns,nt,ans=-1e9,gs[52][26],gt[52][26],f[N][52][52];
    char c[N],s[N],t[N];
    bool Qs(int x,int y)
    {
        int p=x-y;for(int i=1;i<=y;i++)if(s[i]!=s[p+i])return 0;
        return 1;
    }
    bool Qt(int x,int y)
    {
        int p=x-y;for(int i=1;i<=y;i++)if(t[i]!=t[p+i])return 0;
        return 1;
    }
    void upd(int&x,int y){x=x>y?x:y;}
    int main()
    {
        scanf("%s",c+1),n=strlen(c+1);
        scanf("%s",s+1),ns=strlen(s+1);
        scanf("%s",t+1),nt=strlen(t+1);
        for(int i=0;i<=ns;i++)
        for(int j=i;j>=0;j--)
        if((i!=ns||j!=ns)&&Qs(i,j))gs[i][s[j+1]-'a']=max(gs[i][s[j+1]-'a'],j+1);
        for(int i=0;i<=nt;i++)
        for(int j=i;j>=0;j--)
        if((i!=nt||j!=nt)&&Qt(i,j))gt[i][t[j+1]-'a']=max(gt[i][t[j+1]-'a'],j+1);
        for(int i=0;i<=n;i++)
        for(int j=0;j<=ns;j++)
        for(int k=0;k<=nt;k++)
        f[i][j][k]=-1e9;
        f[0][0][0]=0;
        for(int i=1;i<=n;i++)
        for(int j=0;j<=ns;j++)
        for(int k=0;k<=nt;k++)
        if(f[i-1][j][k]>-1e9)
        {
            if(c[i]!='*')
            {
                int x=c[i]-'a';
                upd(f[i][gs[j][x]][gt[k][x]],f[i-1][j][k]+(gs[j][x]==ns)-(gt[k][x]==nt));
            }
            else for(int x=0;x<26;x++)
            upd(f[i][gs[j][x]][gt[k][x]],f[i-1][j][k]+(gs[j][x]==ns)-(gt[k][x]==nt));
        }
        for(int j=0;j<=ns;j++)
        for(int k=0;k<=nt;k++)
        upd(ans,f[n][j][k]);
        printf("%d",ans);
    }
    View Code

    E

    太难了,很少有这么难的E。考虑从小到大枚举2的幂次,当答案是x时,然后将每个小于2x的a[i]插入线性基。判断从0~x-1位是否存在即可。找到最大的x后,再重建立一遍线性基,dfs搜索答案即可,每次异或线性基内的数。复杂度O(nlogn),因为可以two-pointers,其中n=max{a[i]}。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=270000;
    int n,ans,a[N],b[20],vis[N];
    vector<int>G;
    void add(int v)
    {
        int tmp=v;
        for(int i=19;i>=0;i--)
        if(v&(1<<i))
        {
            if(b[i])v^=b[i];
            else{G.push_back(tmp),b[i]=v;break;}
        }
    }
    void dfs(int v,int t)
    {
        printf("%d ",v);
        vis[v]=1;
        if(t==(1<<ans))return;
        for(int i=0;i<G.size();i++)if(!vis[v^G[i]]){dfs(v^G[i],t+1);break;}
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        for(int i=1,p=1;i<=19;i++)
        {
            while(p<=n&&a[p]<(1<<i))add(a[p++]);
            bool flag=1;
            for(int j=0;j<i;j++)if(!b[j])flag=0;
            if(flag)ans=i;
        }
        memset(b,0,sizeof b);
        G.clear();
        for(int i=1;i<=n;i++)if(a[i]<(1<<ans))add(a[i]);
        printf("%d
    ",ans);
        sort(G.begin(),G.end());
        unique(G.begin(),G.end());
        dfs(0,1);
    }
    View Code

    F

    太难了,先咕着。

    这场CF是真心难,所以导致其成为手速场,体现不了选手的真实水平。用小号的小号打的,就会ABCD,rank5,rating+=291。感觉自己稍微有点难度的题都不会。

  • 相关阅读:
    python中读取文件数据时要注意文件路径
    sklearn.model_selection 的 train_test_split作用
    matplotlib中subplot的各参数的作用
    用梯度下降算法求最值
    AfxMessageBox与MessageBox用法与区别
    MFC、API、C++三者的区别
    2、CString与string借助char *互转
    1、创建MFC应用程序——单个文档
    1、Mat类的属性、方法
    CMake编译OpenCV
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/10842345.html
Copyright © 2011-2022 走看看