Codeforces #494 A~E (7.3)

本文总结了CodeForces比赛经历,包括A至E题的解题思路及代码实现,涉及贪心算法、二进制表示、树的构建等关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这把状态奇差,可能是因为令人崩溃的蚊子数量……做完D就快没时间了,E又坑多
A 瞎搞
http://codeforces.com/contest/1003/problem/A

#include<bits/stdc++.h>
using namespace std;
int a[100];
int mm;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        int x;
        scanf("%d",&x);
        a[x]++;
        mm=max(mm,a[x]);
    }
    printf("%d",mm);
}

B 瞎搞(出奇的烦)

#include<bits/stdc++.h>
using namespace std;
int s[202];
int main()
{
    int a,b,x;
    scanf("%d%d%d",&a,&b,&x);
    int aa=a,bb=b;
    if(x%2==1)
    {
        a-=(x-1)/2;
        b-=(x-1)/2;
        int c=(x-1)/2;
        int j=0;
        while(a--)
        {
            s[j++]=0;
            //printf("s %d %d\n",j-1,s[j-1]);
        }
        while(b--)
        {
            s[j++]=1;
            //printf("s'' %d %d\n",j-1,s[j-1]);
        }
        while(c--)
        {
            s[j++]=0;
            s[j++]=1;
        }
    }
    else
    {
        if(a>b)
        {
            int c=x/2;int d=x/2-1;
            a-=c;
            b-=d;
            int j=0;
            while(a--)
            {
                s[j++]=0;
            }
            while(b--)
            {
                s[j++]=1;
            }
            s[j++]=0;
            while(d--)
            {
                s[j++]=1;
                s[j++]=0;
            }
        }
        else
        {
            int c=x/2;int d=x/2-1;
            a-=d;
            b-=c;
            int j=0;
            while(b--)
            {
                s[j++]=1;
            }
            while(a--)
            {
                s[j++]=0;
            }
            s[j++]=1;
            while(d--)
            {
                s[j++]=0;
                s[j++]=1;
            }
        }
    }
//  printf("yrs,%d %d\n",s[0],s[2]);
//  printf("%d\n",a+b);
    for(int i=0;i<aa+bb;i++)
    {
        cout<<s[i];
    }
}

C 暴力(数据量估算一下,优化好暴力可以过,这题一个小错卡了好久)

#include<bits/stdc++.h>
using namespace std;
int a[5005],bs[5005],su;
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        su+=a[i];
        bs[i]=su;
    //  printf("%d ",bs[i]);
    }
    double mmm=0;
    for(int i=k;i<=n;i++)
    {
        int nm=bs[i],mm=bs[i];
        for(int r=1;r<=n-i;r++)
        {
        //  printf("r %d\n",r);
            nm+=a[i+r];
            nm-=a[r];
            mm=max(mm,nm);
        }
        double c=mm*(double)1.0/i;
        mmm=max(mmm,c);
    }
//  printf("%.10lf",mmm);
cout<<setprecision(15)<<mmm;
}

D 贪心
题目基本明说了跟二进制表示有关,可以证明必须优先满足大的二进制位,如果没有对应硬币就往下推,用栈存二进制位,大的后进先出。

#include<bits/stdc++.h>
using namespace std;
int a[32];
int main()
{
    int n,q;
    scanf("%d%d",&n,&q);
    for(int i=0;i<n;i++)
    {
        int x;
        scanf("%d",&x);
        int j=0;
        x/=2;
        while(x)
        {
            x/=2;
            j++;
        }
        a[j]++;
    }
    int b[32];
        for(int j=0;j<q;j++)
    {
            for(int i=0;i<32;i++){
        b[i]=a[i];
    //  printf("i %d bi %d ",i,b[i]);
    }
        int x;
        int ans=0;
        int flg=0;
        scanf("%d",&x);
        stack<int> qq;
        int k=0;
        while(x)
        {
            if(x&1)qq.push(k);
            k++;
            x>>=1;
        }
    //  printf("sz %d\n",qq.size());
        while(!qq.empty())
        {
            int c=qq.top();
        //  printf("c:%d\n",c);
            qq.pop();
            int k=c;
            int scale=1;
            while(scale)
            {
                //printf("k %d b[k] %d scale %d\n",k,b[k],scale);
                if(b[k]>=scale)
                {
                //  printf("b k %d-=scale %d",k,scale);
                    b[k]-=scale;
                    ans+=scale;
                    scale=0;
                }
                else{
                    //b[k]=0;
                    //  printf("scale %d k %d\n",scale,k);
                    scale-=b[k];
                    ans+=b[k];
                    b[k]=0;
                    scale*=2;
                    k--;
                }
                if(k<0)break;
            }
            if(scale){
                flg=1;
                //break;
            }
        }
        if(flg==1)printf("-1\n");
        else printf("%d\n",ans);
    }
}

E 建树
大坑1 :d(半径)是最长路径长度,不是你搜索时树的深度
大坑2: k可以为1(这个被卡到爆炸)
先构造一条路径,从两边向中间添加树枝,应该是中间可以加最深的树,每个都深搜一遍,如果到了n就结束,最后没到n就NO。

#include<bits/stdc++.h>
using namespace std;
int n,d,k;
#define N 400005
int doo[N],maxdep[N];
int nown;
vector<int> eg[N];
void dfs(int dep,int rt,int mdep)
{
//  printf("dfs %d depth %d\n",rt,dep);
    if(dep>mdep)return;
    if(nown==n)return;
    while(doo[rt]<k)
    {
        nown++;
        eg[nown].push_back(rt);
        doo[nown]++;
        doo[rt]++;
        dfs(dep+1,nown,mdep);
        if(nown==n)break;
    }
    return;
}
int main()
{
    scanf("%d%d%d",&n,&d,&k);
    doo[1]++;doo[d+1]++;
    if(d+1>n)
    {
        printf("NO");
        return 0;
    }
    //eg[1].push_back(2);
    eg[d+1].push_back(d);//从后向前表示 
    for(int i=2;i<=d;i++)
    {
        eg[i].push_back(i-1);
        //eg[i].push_back(i+1);
        doo[i]+=2;
        if(doo[i]>k)
        {
            printf("NO");
            return 0;
        }
        maxdep[i]=min(i-1,d+1-i);
        //printf("maxdep %d is %d\n",i,maxdep[i]);
    }
    nown=d+1;
    for(int i=2;i<=d;i++)
    {
        if(nown==n)break;
        dfs(1,i,maxdep[i]);
    }
    if(nown<n)
    {
        printf("NO");
        return 0;
    }
    else
    {
        printf("YES\n");
        for(int i=1;i<=nown;i++)
        {
            if(eg[i].size()>0)
                printf("%d %d\n",i,eg[i][0]);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_viceversa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值