Avito Code Challenge 2018 A~E

Posted lokiii

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Avito Code Challenge 2018 A~E相关的知识,希望对你有一定的参考价值。

A. Antipalindrome

还以为是什么神dp结果就是分情况讨论啊
原串是一串一样的字符的话输出0,是回文串的话输出n-1,否则直接输出原串长度

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=55;
int n;
char s[N];
int main()
{
    scanf("%s",s+1);
    n=strlen(s+1);
    int f=1;
    for(int i=1;i<n;i++)
        if(s[i]!=s[i+1])
        {
            f=0;
            break;
        }
    if(f)
    {
        puts("0");
        return 0;
    }
    f=1;
    for(int i=1;i<=n/2;i++)
        if(s[i]!=s[n-i+1])
        {
            f=0;
            break;
        }
    printf("%d\n",n-f);
    return 0;
}

B. Businessmen Problems

hash一下,然后对每个化学元素取收入最大值即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
const int N=200005;
int n,m,a[N],b[N],c[N],d[N],g[N],tot,has,ans[N];
long long sum;
map<int,int>mp;
int read()
{
    int r=0,f=1;
    char p=getchar();
    while(p>‘9‘||p<‘0‘)
    {
        if(p==‘-‘)
            f=-1;
        p=getchar();
    }
    while(p>=‘0‘&&p<=‘9‘)
    {
        r=r*10+p-48;
        p=getchar();
    }
    return r*f;
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
        a[i]=read(),c[i]=read(),g[++tot]=a[i];
    m=read();
    for(int i=1;i<=m;i++)
        b[i]=read(),d[i]=read(),g[++tot]=b[i];
    sort(g+1,g+1+tot);
    for(int i=1;i<=tot;i++)
        if(i==1||g[i]!=g[i-1])
            mp[g[i]]=++has;
    for(int i=1;i<=n;i++)
        ans[mp[a[i]]]=c[i];
    for(int i=1;i<=m;i++)
        ans[mp[b[i]]]=max(ans[mp[b[i]]],d[i]);
    for(int i=1;i<=has;i++)
        sum+=1ll*ans[i];
    printf("%lld\n",sum);
    return 0;
}

C. Useful Decomposition

有三种可能情况:所有链在某一点上相交,也就是只有一个点度数>2;只有一条链,就是两个点度数为1,其他点度数为2;不符合要求的情况,就是有超过一个点度数>2

#include<iostream>
#include<cstdio>
using namespace std;
const int N=200005;
int n,d[N],sum,con,p,ans[N],tot;
int read()
{
    int r=0,f=1;
    char p=getchar();
    while(p>‘9‘||p<‘0‘)
    {
        if(p==‘-‘)
            f=-1;
        p=getchar();
    }
    while(p>=‘0‘&&p<=‘9‘)
    {
        r=r*10+p-48;
        p=getchar();
    }
    return r*f;
}
int main()
{
    n=read();
    for(int i=1;i<n;i++)
    {
        int x=read(),y=read();
        d[x]++,d[y]++;
    }
    for(int i=1;i<=n;i++)
    {
        if(d[i]>2)
            p=i,sum++;
        if(d[i]==1)
            ans[++tot]=i,con++;
    }
    if(sum>1)
    {
        puts("No");
        return 0;
    }
    if(sum==0)
    {
        printf("Yes\n1\n%d %d\n",ans[1],ans[2]);
        return 0;
    }
    printf("Yes\n%d\n",con);
    for(int i=1;i<=n;i++)
        if(d[i]==1)
            printf("%d %d\n",p,i);
    return 0;
}

D. Bookshelves

很好的dp
或许应该叫按位贪心?从高位到低位枚举,然后f[i][j]表示到j为止分为i段能否让当前枚举的位为1,转移的时候也要注意满足之前枚举的位能不变为0

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=55;
int n,k;
long long a[N],ans;
bool f[N][N];
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++)
        scanf("%lld",&a[i]);
    for(int i=60;i>=0;i--)
    {
        memset(f,0,sizeof(f));
        f[0][0]=1;
        for(int j=0;j<k;j++)
            for(int l=0;l<n;l++)
                if(f[j][l])
                {
                    long long sum=0;
                    for(int d=l;d<n;d++)
                    {
                        sum+=a[d];
                        if((sum&ans)==ans&&(sum&(1ll<<i)))
                            f[j+1][d+1]=1;
                    }
                }
        if(f[k][n])
            ans|=1ll<<i;
    }
    printf("%lld\n",ans);
    return 0;
}

E. Addition on Segments

还是非常好的dp
设f[i]为i为最大值时出现的最右位置,然后把修改操作按r排序,每次用修改操作更新f即可

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=10005;
int n,q,f[N];
struct qwe
{
    int l,r,x;
}a[N];
bool cmp(const qwe &a,const qwe &b)
{
    return a.r<b.r;
}
int read()
{
    int r=0,f=1;
    char p=getchar();
    while(p>‘9‘||p<‘0‘)
    {
        if(p==‘-‘)
            f=-1;
        p=getchar();
    }
    while(p>=‘0‘&&p<=‘9‘)
    {
        r=r*10+p-48;
        p=getchar();
    }
    return r*f;
}
int main()
{
    n=read(),q=read();
    for(int i=1;i<=q;i++)
        a[i].l=read(),a[i].r=read(),a[i].x=read();
    sort(a+1,a+1+q,cmp);
    for(int i=1;i<=q;i++)
    {
        for(int j=n-a[i].x;j>=1;j--)
            if(f[j]>=a[i].l)
                f[j+a[i].x]=max(f[j+a[i].x],f[j]);
        f[a[i].x]=a[i].r;
    }
    int ans=0;
    for(int i=1;i<=n;i++)
        if(f[i]>0)
            ans++;
    printf("%d\n",ans);
    for(int i=1;i<=n;i++)
        if(f[i]>0)
            printf("%d ",i);
    return 0;
}

以上是关于Avito Code Challenge 2018 A~E的主要内容,如果未能解决你的问题,请参考以下文章

cf掉分记——Avito Code Challenge 2018

Avito Code Challenge 2018 A~E

ODT&(Avito Code Challenge 2018 G题)

[Avito Code Challenge 2018 G] Magic multisets(线段树)

Avito Cool Challenge 2018 Solution

Avito Cool Challenge 2018 C. Colorful Bricks 排列组合