[欢乐赛]20171024

Posted wisdom_jie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[欢乐赛]20171024相关的知识,希望对你有一定的参考价值。

1.分火腿

考试时想用循环加特判写,最后发现写一个gcd就够了

#include<cstdio>

int gcd(int a,int b)
{
    int r=a%b;
    while(r!=0)
    {        
        a=b;
        b=r;
        r=a%b;
    }
    return b;
}
int main()
{
    freopen("hdogs.in","r",stdin);
    freopen("hdogs.out","w",stdout);
    int T,a,b,x,ans;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&a,&b);
        if(a%b==0){printf("0\n");continue;}
        a=a-b*(a/b);
        x=gcd(a,b);
        x=a/x;
        ans=b-1-(a-1)/x;
        printf("%d\n",ans);
    }
    return 0;
}

2.无聊的会议

用del不同颜色等腰三角形个数,不同色必然有两个异色点,可以用这两个异色点确定三角形然后去重并去掉等边三角形的重复计算。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int T,n;
char a[1000005];
ll calcu()
{
    ll ans=0;
    ans=(ll) n*((n-1)/2);
    if(n%3==0) ans-=n/3*2;
    return ans;
}
ll del()
{
    ll ans;
    if(n%2==1)
    {
        int s1=0,i,s0=0;
        for(i=0;i<n;i++)
        {
            if(a[i]==0) s0++;
            else s1++;
        }
        ans=(ll)s1*s0*3;
        if(n%3==0)
        {
            s1=n/3; s0=n/3*2;
            for(i=0;i<n;i++)
            {
                if(a[i]!=a[(i+s1)%n]) ans--;
                if(a[i]!=a[(i+s0)%n]) ans--;
            }
        }
        return ans/2;
    }
    else
    {
        int i,s00=0,s01=0,s10=0,s11=0;
        for(i=0;i<n;i+=2)
        {
            if(a[i]==0) s00++;
            else s01++;
        }
        for(i=1;i<n;i+=2)
        {
            if(a[i]==0) s10++;
            else s11++;
        }
        ans=(ll)s00*s11*2; ans+=(ll)s01*s10*2;
        ans+=(ll)s00*s01*4; ans+=(ll)s10*s11*4;
        int n1,n2;
        n1=n/2;
        for(i=0;i<n;i++)
        {if(a[i]!=a[(i+n1)%n]) ans--;}
        if(n%3==0)
        {
            int s1=n/3,s0=n/3*2;
            for(i=0;i<n;i++)
            {
                if(a[i]!=a[(i+s1)%n]) ans--;
                if(a[i]!=a[(i+s0)%n]) ans--;
            }
        }
        return ans/2;
    }
}
int main()
{
    freopen("meeting.in","r",stdin);
    freopen("meeting.out","w",stdout);
    scanf("%d",&T);
    int k;
    for(k=1;k<=T;k++)
    {
        scanf("%s",a); n=strlen(a);
        printf("Case %d: %lld\n",k,calcu()-del());
    }
    return 0;
}

3.班服

此题在考试时用for循环暴力,过了40%。

正确方法:状压DP

数据n范围较小(10),可以用二进制数来表示n被选择的状态,末状态是(1<<n)-1。要处理班级与服装的关系,需在读入时让服装来存储班级的信息才能方便转移。

参考代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mod=1e9+7;
int T,n,x,mp[110][110],f[110][1<<11];
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(mp,0,sizeof(mp));
        memset(f,0,sizeof(f));
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            while(1)
            {
                scanf("%d",&x);
                mp[x][++mp[x][0]]=i;
                char ch=getchar();
                if(ch==\n) break;
            }
        }
        f[0][0]=1;
        for(int i=1;i<=100;++i)
            for(int j=0;j<(1<<n);++j)
            {
                f[i][j]+=f[i-1][j];
                for(int k=1;k<=mp[i][0];++k)
                if(j&(1<<mp[i][k]-1))
                    (f[i][j]+=f[i-1][j-(1<<mp[i][k]-1)])%=mod;
            }
        printf("%d\n",f[100][(1<<n)-1]);
     }
     return 0;
}

 

以上是关于[欢乐赛]20171024的主要内容,如果未能解决你的问题,请参考以下文章

欢乐结训赛题解

Comet OJ - 2019 六一欢乐赛

i春秋第二届春秋欢乐赛-Web-Hello World

欢乐赛解题报告

一起来做题~欢乐赛1 A(思维)

综合-某假期欢乐赛 (Apri, 2018)