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

    A

    签到(code不贴了)

    PS:以后cf div2A(有时还有B)和atcoder <=200分(有时<=300)的题目不再贴code,不过可能也没几次比赛记录了。

    B

    高精度,枚举位数最短的可能,然后计算两个即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+7;
    struct node{int n,a[N];}ans,a,b;
    int n,mn;
    vector<int>G;
    char s[N];
    bool check(node a,node b)
    {
        if(a.n!=b.n)return a.n<b.n;
        for(int i=a.n;i;i--)
        if(a.a[i]<b.a[i])return 1;
        else if(a.a[i]>b.a[i])return 0;
        return 0;
    }
    node operator+(node a,node b)
    {
        if(a.n<b.n)swap(a,b);
        for(int i=1;i<=a.n;i++)
        {
            a.a[i]+=b.a[i];
            if(a.a[i]>=10)a.a[i]-=10,a.a[i+1]++;
        }
        if(a.a[a.n+1])a.n++;
        return a;
    }
    void split(int p)
    {
        a.n=p;
        for(int i=1;i<=p;i++)a.a[p-i+1]=s[i]-'0';
        for(int i=p+1;i<N;i++)a.a[i]=0;
        b.n=n-p;
        for(int i=p+1;i<=n;i++)b.a[n-i+1]=s[i]-'0';
        for(int i=n-p+1;i<N;i++)b.a[i]=0;
        a=a+b;
        if(check(a,ans))ans=a;
    }
    int main()
    {
        scanf("%d",&n);
        if(n==2){cin>>n,cout<<n/10+n%10;return 0;}
        scanf("%s",s+1);
        mn=n+2,ans.n=n+2;
        for(int i=1;i<n;i++)
        if(s[i+1]!='0')
        {
            int len=max(i,n-i);
            if(len<mn)mn=len,G.clear(),G.push_back(i);
            else if(len==mn)G.push_back(i);
        }
        for(int i=0;i<G.size();i++)split(G[i]);
        for(int i=ans.n;i;i--)printf("%d",ans.a[i]);
    }
    View Code

    C

    太难了吧,简直被搞自闭了,WA了3发,主要是细节过多。实际上就是一个朴素O(nm)DP,f[i][j]表示以(i,j)为右下角的旗子个数,然后u[i][j]表示同色往上走的距离,注意第一段的距离是>=后面两端,而不是=,第二发这里WA了。第一发是只判了长度没判颜色。第三发是把长度都默认成1了。严重影响做题心态。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1007;
    int n,m,u[N][N];
    ll ans,f[N][N];
    char a[N][N];
    int check(int i,int j)
    {
        int len=u[i][j];
        i-=u[i][j];
        if(u[i][j]!=len)return 0;
        i-=u[i][j];
        return len*(u[i][j]>=len);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%s",a[i]+1);
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        if(i==1||a[i][j]!=a[i-1][j])u[i][j]=1;
        else u[i][j]=u[i-1][j]+1;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            int v=check(i,j);
            if(!v)continue;
            f[i][j]=1;
            if(j>1&&v==check(i,j-1)&&a[i][j]==a[i][j-1]&&a[i-v][j]==a[i-v][j-1]&&a[i-2*v][j]==a[i-2*v][j-1])f[i][j]+=f[i][j-1];
            ans+=f[i][j];
        }
        cout<<ans;
    }
    View Code

    D

    离线做法显然,把询问从小到大排序,然后扫的时候记录扫到了第几层(如果全部填满特判一下,很简单qwq),对于其余的次数,可以做一棵权值线段树。

    其实这题真的可以加强,加强法是把n设为1e5,然后强制在线(讲真这是我第一想法,不过比较难写)。

    #include<bits/stdc++.h>
    using namespace std;
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    typedef long long ll;
    const int N=5e5+7;
    struct node{ll x;int id;}q[N];
    int n,m,Q,mx,ans[N],sum[N<<2],sz[N];
    ll s[N];
    vector<int>G[N];
    bool cmp(node a,node b){return a.x<b.x;}
    void update(int k,int l,int r,int rt)
    {
        if(l==r){sum[rt]=1;return;}
        int mid=l+r>>1;
        if(k<=mid)update(k,lson);else update(k,rson);
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    int query(int v,int l,int r,int rt)
    {
        if(l==r)return l;
        int mid=l+r>>1;
        if(v>sum[rt<<1])return query(v-sum[rt<<1],rson);
        return query(v,lson);
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&Q);
        for(int i=1,x;i<=n;i++)scanf("%d",&x),s[x]++,mx=max(mx,(int)s[x]);
        for(int i=1;i<=m;i++)G[s[i]].push_back(i);
        for(int i=1;i<=Q;i++)scanf("%I64d",&q[i].x),q[i].id=i,q[i].x-=n;
        sort(q+1,q+Q+1,cmp);
        for(int i=0;i<=mx;i++)sort(G[i].begin(),G[i].end()),s[i]=0;
        sz[0]=G[0].size();for(int i=1;i<=mx;i++)sz[i]=sz[i-1]+G[i].size();
        s[0]=sz[0];for(int i=1;i<=mx;i++)s[i]=s[i-1]+sz[i];
        for(int i=0;i<G[0].size();i++)update(G[0][i],1,m,1);
        for(int i=1,p=0;i<=Q;i++)
        if(s[mx]<q[i].x)ans[q[i].id]=(q[i].x-s[mx]-1)%m+1;
        else{
            while(p<=mx&&s[p]<q[i].x)
            {
                p++;
                for(int i=0;i<G[p].size();i++)update(G[p][i],1,m,1);
            }
            if(p)q[i].x-=s[p-1];
            ans[q[i].id]=query(q[i].x,1,m,1);
        }
        for(int i=1;i<=Q;i++)printf("%d
    ",ans[i]);
    }
    View Code

    E

    咕。

    result:rank37 rating+=157,毕竟这是我第4个号……

  • 相关阅读:
    软件测试作业1:android手机应用布局之TabActivity
    软件测试作业2:对faulty,error和failure的理解和应用
    python-字符串常用方法、文件简单读写
    python-字典练习题
    python-字典
    python-list 列表 数组
    python基础一循环
    Charles抓包
    Jmeter分布式
    Jmeter如何操作数据库
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/11037203.html
Copyright © 2011-2022 走看看