Codeforces8VC Venture Cup 2016 - Elimination RoundA---F

本文深入探讨了算法、编程工具、开发环境等信息技术领域的关键概念与应用实例,旨在为开发者提供全面的技术指导与实践洞察。

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

A. Robot Sequence
题意:给定一个字符串,每个字符代表向上下左右其中方向移动一个单位,找出能回到原位置的子串数目。
暴力枚举.

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define mx 1e9
#define lowbit(x) (x&(-x))
#define N 505
using namespace std;
char s[222];
int a[222],b[222],n,ans;
int main()
{
    scanf("%d%s",&n,s+1);
    for(int i=1;i<=n;i++)
    {
        a[i]=a[i-1];
        b[i]=b[i-1];
        if(s[i]=='L')a[i]++;
        if(s[i]=='R')a[i]--;
        if(s[i]=='U')b[i]++;
        if(s[i]=='D')b[i]--;
    }
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            if(a[j]-a[i-1]==0&&b[j]-b[i-1]==0)
                ans++;
    cout<<ans;
    return 0;
}

B. Cards
题意:给定一个只包含三个颜的序列,每次刻意把两个相同的颜色消成一个或者把2个不同的颜色消成另外一个颜色,问消完后最后一个颜色可能是什么。
如果序列只有1个颜色或3个颜色,那么答案就是这些颜色,对两个颜色的特判一下,也非常简单.

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define mx 1e9
#define lowbit(x) (x&(-x))
#define N 505
using namespace std;
char s[N];
int R,B,G,n;
int sum;
int main()
{
    scanf("%d%s",&n,s);
    for(int i=0;i<n;i++)
        R+=(s[i]=='R'),
        B+=(s[i]=='B'),
        G+=(s[i]=='G');
    sum=(R!=0)+(B!=0)+(G!=0);
    if(sum==3) puts("BGR");
    else if(sum==1)
    {
        if(R)puts("R");
        if(B)puts("B");
        if(G)puts("G");
    }
    else
    {
        if(R==0)
        {
            if(B==1)
            {
                if(G==1)puts("R");
                else puts("BR");
            }
            else
            {
                if(G==1)puts("GR");
                else  puts("BGR");
            }
        }
        else if(B==0)
        {
            if(G==1)
            {
                if(R==1)puts("B");
                else puts("BG");
            }
            else
            {
                if(R==1)puts("BR");
                else puts("BGR");
            }
        }
        else if(G==0)
        {
            if(B==1)
            {
                if(R==1)puts("G");
                else puts("BG");
            }
            else
            {
                if(R==1)puts("GR");
                else puts("BGR");
            }
        }
    }
    return 0;
}

C. Block Towers
题意:给定n和m,找出n个2的倍数和m个三的倍数,这所有的数都不能重复,问最大值最小是多少。
做法:从小到大找出比原范围稍大的所有的2的倍数和3的倍数,因为有的数既是2的倍数又是3的倍数,所以统计一下到当前的数有多少个2的倍数( s2 数组),多少个3的倍数( s3 数组),然后从n+m向后枚举,找到第一个 s2[i]>=m s3[i]>=n 的数即为答案。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define mx 1e9
#define lowbit(x) (x&(-x))
#define N 505
using namespace std;
int a[3030030],s2[3003030],s3[3030030];
int n,m,W,tot;
int main()
{
    cin>>n>>m;
    W=max(n,m)+min(n,m)/2+20;
    int l1=1,l2=1;
    while(l1<=W||l2<=W)
    {
        int x=l1*2,y=l2*3;
        if(x<=y)
        {
            if(x!=a[tot])
                a[++tot]=x,s2[tot]=s2[tot-1]+1,s3[tot]=s3[tot-1];
            else
                s2[tot]++;
            l1++;
        }
        else
        {
            if(y!=a[tot])
                a[++tot]=y,s3[tot]=s3[tot-1]+1,s2[tot]=s2[tot-1];
            else
                s3[tot]++;
            l2++;
        }
        //cout << tot <<": "<<a[tot]<<" "<<s2[tot]<<" "<< s3[tot]<< endl;
    }
    for(int i=n+m;i<=tot;i++)
        if(s2[i]>=n&&s3[i]>=m)
        {
            cout<<a[i]<<endl;
            return 0;
        }
    return 0;
}

D. Jerry’s Protest
题意:给定一个序列,二人随机从序列中拿一个数(放回)谁的大算谁赢,比赛三局两胜,已知A与B的比赛结果为前两局A胜,第三局B胜,然后求这三局B取得数的和比A取得数的和大的概率。
做法显然是dp,求出前两局A的总和比B大 x 的概率f[x],第三局B比A大 x F[x],然后求一个 f[x] 的前缀和,枚举x最后再求总概率。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x&(-x))
#define N 505
using namespace std;
int sc()
{
    int i=0; char c=getchar();
    while(c>'9'||c<'0')c=getchar();
    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
    return i;
}
double F[10050],f[10050],sum,ans;
int a[2222],n,mx;
int main()
{
    n=sc();
    for(int i=1;i<=n;i++)a[i]=sc();
    sort(a+1,a+n+1);
    sum=n*(n-1)/2;
    for(int i=1;i<n;i++)
        for(int j=i+1;j<=n;j++)
            F[a[j]-a[i]]+=(double)1/sum;
    mx=a[n]-a[1];
    for(int i=1;i<=mx;i++)
        for(int j=1;j<=mx;j++)
            f[i+j]+=F[i]*F[j];
    for(int i=1;i<=mx;i++) f[i]+=f[i-1];//cout<<f[i]<<endl;
    for(int i=1;i<=mx;i++)
        ans+=F[i]*f[i-1];
    printf("%.10lf",ans);
    return 0;
}

E. Simple Skewness
题意:给定一个序列,从序列中选出一些数使得平均数减去中位数最大。
枚举中位数,发现 f(x) 是单峰函数( x 是序列长度)然后三分序列长度找出极值,可以证明序列长度为奇数时肯定存在最优解。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x&(-x))
#define N 505
using namespace std;
int sc()
{
    int i=0; char c=getchar();
    while(c>'9'||c<'0')c=getchar();
    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
    return i;
}
double mx=-1;
int R,L,mid,n;
int a[200200];
long long sum[200200];
double solve(int x,int L)
{
    return (double)(sum[x]-sum[x-L-1]+sum[n]-sum[n-L])/(2*L+1);
}
void cal(int x)
{
    int l=0,r=min(n-x,x-1);
    while(r-l>10)
    {
        int lmid=l+(r-l+1)/3;
        int rmid=r-(r-l+1)/3;
        double ansl=solve(x,lmid);
        double ansr=solve(x,rmid);
        if(ansr>ansl)l=lmid;else r=rmid;
    }
    for(int i=l;i<=r;i++)
    {
        double now=solve(x,i)-a[x];
        if(now>mx)
            mx=now,mid=x,L=i,R=i;
    }
}
int main()
{
    n=sc();
    for(int i=1;i<=n;i++)a[i]=sc();
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
        sum[i]+=sum[i-1]+a[i];
    for(int i=1;i<=n;i++)
        cal(i);
    printf("%d\n",2*L+1);
    for(int i=1;i<=L;i++)
        printf("%d %d ",a[mid-i],a[n-i+1]);
    if(R!=L)printf("%d ",a[mid+1]);
    printf("%d",a[mid]);
    return 0;
}

F. Group Projects
题意:给定一个序列,然后给里面的数任意分组,每一组的权值为这组数中的最大值减去最小值,问所有权值之和<=k的情况下有多少种分组方案。
先排序,然后动态规划,f[i][j][k]表示前 i 个数,还有j组未确定最大的数(有 j 组要继续添加数),当前的权值总和为k的方案数.然后转移就是枚举 i ,当前的数可以插入到未确定的j组中,也可以单独分出一组,然后考虑差分,无论当前的 c[i] 怎么插入,对k的贡献都是 j(c[i]c[i1])

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x&(-x))
#define R 1000000007
#define ll long long
using namespace std;
int sc()
{
    int i=0; char c=getchar();
    while(c>'9'||c<'0')c=getchar();
    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
    return i;
}
int c[222];
ll a[202][1002],b[202][1002];
int n,k;
int main()
{
    n=sc(),k=sc();
    for(int i=1;i<=n;i++)c[i]=sc();
    sort(c+1,c+n+1);
    c[0]=c[1];
    a[0][0]=1;
    for(int i=1;i<=n;i++)
    {
        swap(a,b);
        memset(a,0,sizeof(a));
        for(int j=0;j<i;j++)
            for(int l=0;l<=k;l++)
                if(l+j*(c[i]-c[i-1])<=k)
                {
                    a[j][l+j*(c[i]-c[i-1])]=(a[j][l+j*(c[i]-c[i-1])]+b[j][l])%R;
                    if(j)
                    {
                        a[j-1][l+j*(c[i]-c[i-1])]=(a[j-1][l+j*(c[i]-c[i-1])]+(ll)j*b[j][l]%R)%R;
                        a[j][l+j*(c[i]-c[i-1])]=(a[j][l+j*(c[i]-c[i-1])]+(ll)j*b[j][l])%R;
                    }
                    a[j+1][l+j*(c[i]-c[i-1])]=(a[j+1][l+j*(c[i]-c[i-1])]+b[j][l])%R;
                }
    }
    ll ans=0;
    for(int i=0;i<=k;i++)
        ans=(ans+a[0][i])%R;
    cout<<ans;
    return 0;
}   

G. Raffles
好虚..据说是线段树

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值