2018 CCPC 吉林站

题目链接

细胞色素(Cytochorme)训练4

The Fool

题意:求判断:n/i(向下取整),i从1到n的和是奇数还是偶数。

程磊说这题是整除分块,但实际上打表找规律非常简单。

#include<bits/stdc++.h>
#define mem(a,b) memset((a),b,sizeof(a))
#define de cout<<endl<<endl<<endl
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=100010;
using namespace std;
ll n;
int main()
{
    int TT=0;
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%lld",&n);
        ll k=sqrt(n);
        if(k%2==1)
            printf("Case %d: odd\n",++TT);
        else
            printf("Case %d: even\n",++TT);
    }
    return 0;
}

The World

题意:给你A地的时间,然后给你AB两地所在时区,让你计算B地的时间。

有几个坑点,就是小时的取值范围是1到12,半夜12点表示为12:00AM,中午12:00表示为12:00PM。并且半夜12点是新的一天的开始。

还有就是,我的代码写的太烂了,又臭又长。看了别人的代码,发现自己是真的烂。

下面是我最开始写的代码:(又臭又长)

#include <bits/stdc++.h>
using namespace std;

char a[110],b[110],c[110];
char m[110];
int main()
{
    int T;scanf("%d",&T);
    int TT=0;
    while(T--)
    {
        getchar();
        gets(a);
        int p1,p2;
        int len=strlen(a);
//开始就是这里写错了
//        if(strcmp(a,"12:00 AM")==0)
//            strcpy(a,"0:00 AM");
//        if(strcmp(a,"12:00 PM")==0)
//            strcpy(a,"0:00 PM");
        for(int i=0;i<len;i++)
        {
            if(a[i]==':')
                p1=i;
        }
        int h;
        if(p1==1)
            h=a[0]-'0';
        else
            h=(a[0]-'0')*10+(a[1]-'0');
        if(h==12)
            h=0;
        for(int i=0;i<len;i++)
            if(a[i]==' ')
                p2=i;
        for(int i=p1+1;i<=p2-1;i++)
            m[i-p1-1]=a[i];
        if(a[p2+1]=='P')
            h+=12;
        scanf("%s%s",b,c);
        int q1,q2;
        if(strcmp(b,"Beijing")==0)
            q1=8;
        if(strcmp(b,"Washington")==0)
            q1=-5   ;
        if(strcmp(b,"London")==0)
            q1=0;
        if(strcmp(b,"Moscow")==0)
            q1=3;

        if(strcmp(c,"Beijing")==0)
            q2=8;
        if(strcmp(c,"Washington")==0)
            q2=-5   ;
        if(strcmp(c,"London")==0)
            q2=0;
        if(strcmp(c,"Moscow")==0)
            q2=3;
        printf("Case %d: ",++TT);
        int q=q2-q1;
        h+=q;
        if(h>=24)
        {
            h-=24;
            printf("Tomorrow ");
            if(h>=12)
            {
                if(h-12==0)
                    printf("12:");
                else
                    printf("%d:",h-12);
                for(int i=0;i<p2-p1-1;i++)
                    printf("%c",m[i]);
                printf(" PM\n");
            }
            else
            {
                if(h==0)
                    printf("12:");
                else
                    printf("%d:",h);
                for(int i=0;i<p2-p1-1;i++)
                    printf("%c",m[i]);
                printf(" AM\n");
            }
            continue;
        }
        if(h<0)
        {
            h+=24;
            printf("Yesterday ");
            if(h>=12)
            {
                if(h-12==0)
                    printf("12:");
                else
                    printf("%d:",h-12);
                for(int i=0;i<p2-p1-1;i++)
                    printf("%c",m[i]);
                printf(" PM\n");
            }
            else
            {
                if(h==0)
                    printf("12:");
                else
                    printf("%d:",h);
                for(int i=0;i<p2-p1-1;i++)
                    printf("%c",m[i]);
                printf(" AM\n");
            }
            continue;
        }
        printf("Today ");
        if(h>=12)
        {
            if(h-12==0)
                printf("12:");
            else
                printf("%d:",h-12);
            for(int i=0;i<p2-p1-1;i++)
                printf("%c",m[i]);
            printf(" PM\n");
        }
        else
        {
            if(h==0)
                printf("12:");
            else
                printf("%d:",h);
            for(int i=0;i<p2-p1-1;i++)
                printf("%c",m[i]);
            printf(" AM\n");
        }
        continue;
    }
    return 0;
}

然后下面是精简版的:(代码量少,时间还快了一点点)

#include<bits/stdc++.h>
using namespace std;
map<string,int> mp;
string a,b,p;
int main()
{
    mp["Beijing"]=8;
    mp["Washington"]=-5;
    mp["London"]=0;
    mp["Moscow"]=3;
    int TT=0;
    int T;scanf("%d",&T);
    int h,m;
    while(T--)
    {
        scanf("%d:%d",&h,&m);
        cin>>p;
        if(p=="PM"&&h!=12)
            h+=12;
        if(p=="AM"&&h==12)
            h-=12;
        cin>>a>>b;
        h+=(mp[b]-mp[a]);
        printf("Case %d: ",++TT);
        if(h>=24)
            {printf("Tomorrow ");h-=24;}
        else if(h<0)
            {printf("Yesterday ");h+=24;}
        else
            printf("Today ");
        if(h>12)
            printf("%d:%02d ",h-12,m);
        else if(h>0)
            printf("%d:%02d ",h,m);
        else
            printf("12:%02d ",m);
        if(h>=12)
            printf("PM\n");
        else
            printf("AM\n");
    }
    return 0;
}

 The Hermit

题意:看别人的吧,懒得写了。这题如果读懂了,认真想一下,真的超简单。

https://blog.csdn.net/aiyouyou_/article/details/89790003

#include<bits/stdc++.h>
#define mem(a,b) memset((a),b,sizeof(a))
#define de cout<<endl<<endl<<endl
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=100010;
using namespace std;
int n;
ll a[1000010];
int main()
{
    int TT=0;
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            if(i>=2&&(a[i]-2)>=0)
                ans=ans^(a[i]-2);
        }
        printf("Case %d: %lld\n",++TT,ans);
    }
    return 0;
}

Justice

题意:给你n个数a[i],让你把这些数分成两堆,问能够使两堆数的和都大于等于1/2,如果能的话还要输出方案。

归并一下。

实际上当时程磊的代码差一点就对了,只需要把100改成100000就行了......

#include<bits/stdc++.h>
#define mem(a,b) memset((a),b,sizeof(a))
#define de cout<<endl<<endl<<endl
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=1e5+10;
using namespace std;
struct node{
    int v,id,f;
}a[N+10];
bool cmp1(node a1,node a2){
    return a1.v<a2.v;
}
bool cmp2(node a1,node a2){
    return a1.id<a2.id;
}
int n,cnt[N+10];
bool ok(int n,int v)
{
    v--;
    while(v--)
        n/=2;
    if(n>0)
        return true;
    return false;
}
int get(int n,int k)
{
    while(k--)
        n/=2;
    return n;
}
int main()
{
    int T;scanf("%d",&T);int TT=0;
    while(T--)
    {
        scanf("%d",&n);
        mem(cnt,0);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i].v);
            a[i].f=0;
            a[i].id=i;
            if(a[i].v>=N)   continue;
            cnt[a[i].v]++;
        }
        for(int i=N;i>=1;i--)
            cnt[i-1]+=cnt[i]/2;
        if(cnt[0]==0)   {printf("Case %d: NO\n",++TT);continue;}
        printf("Case %d: YES\n",++TT);
        sort(a+1,a+n+1,cmp1);
        mem(cnt,0);
        for(int i=n;i>=1;i--)
        {
            a[i].f=1;
            if(a[i].v>N)
                continue;
            cnt[a[i].v]++;
            if(ok(cnt[a[i].v],a[i].v))
                break;
            if(i!=1)
            {
                if(a[i].v!=a[i-1].v)
                    cnt[a[i-1].v]=get(cnt[a[i].v],a[i].v-a[i-1].v);
            }
        }
        sort(a+1,a+n+1,cmp2);
        for(int i=1;i<=n;i++)
            printf("%d",a[i].f);
        puts("");
    }
    return 0;
}

Strength

题意:懒得写了,看别人的吧。https://blog.csdn.net/dillonh/article/details/96308618

#include<bits/stdc++.h>
#define mem(a,b) memset((a),b,sizeof(a))
#define de cout<<endl<<endl<<endl
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=100010;
using namespace std;
int n,m;
ll a[100010],b[100010];
int c[100010];
ll ans1,ans2,ans;
bool cmp(ll a1,ll a2)
{
    return a1>a2;
}
int main()
{
    int TT=0;
    int T;scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        for(int i=1;i<=m;i++)
            scanf("%lld",&b[i]);
        for(int i=1;i<=m;i++)
            scanf("%d",&c[i]);
        ans1=0;ans2=0;
        int p,q,f,ff;

        //打普通的怪,直接对人造成杀伤   优先用大的打小的
        sort(a+1,a+n+1,cmp);
        sort(b+1,b+m+1);
        p=1;q=1;
        for(int i=p;i<=n;i=p)
        {
            if(q>m)
                break;
            for(int j=q;j<=m;j=q)
            {
                if(a[i]<=b[j]||c[j]==1)
                    {q++;continue;}
                ans1+=(a[i]-b[j]);
                p++;
                q++;
                break;
            }
        }

        //把怪全打死,然后打人造成杀伤   优先用大的打大的
        sort(a+1,a+n+1,cmp);
        sort(b+1,b+m+1,cmp);
        p=1;q=1;f=0;
        for(int i=p;i<=n;i=p)
        {
            if(q>m)
                break;
            for(int j=q;j<=m;j=q)
            {
                if(a[i]<b[j])   //不可能把怪全打死
                    {p++;f++;break;}
                else if(a[i]==b[j])
                    {p++;q++;a[i]=0;break;}
                else
                {
                    if(c[j]==0)
                        {ans2+=a[i]-b[j];b[j]=0;a[i]=0;}
                    else
                        {b[j]=0;a[i]=0;}
                    p++;q++;
                    break;
                }
            }
            if(f)
                break;
        }
        if(f==0)    //已经成功的把怪全打死了
        {
            for(int i=1;i<=n;i++)
                ans2+=a[i];
        }
        ans=max(ans1,ans2);
        printf("Case %d: %lld\n",++TT,ans);
    }
    return 0;
}

The Moon

题意:有两个整数p和q,q的初始值为2,p是输入的数。p表示你赢的的概率为百分之p,如果赢了的话,你有百分之q的概率能拿到你想要的东西,如果你赢了但没有拿到想要的东西,那就让q加上2,如果你没赢,那就让q加上1.5。问你拿到想要的东西所需的比赛次数的期望是多少。

思路:dp。可以直接dp,也可以打表做,不过时间都挺快的,差不多都是15ms过。实际上我感觉很多dp都很简单,当时想不起来主要是没想起来它的状态,如果状态想起来了,那转移方程应该特别好些,以后要大胆的猜想状态......

直接做:

#include<bits/stdc++.h>
#define mem(a,b) memset((a),b,sizeof(a))
#define de cout<<endl<<endl<<endl
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=100010;
using namespace std;
map<pair<int,int>,double> mp;
double solve(int p,int q)
{
    if(q>=200)
        return 100.0/p;
    if(mp.count(make_pair(p,q))!=0)
        return mp[make_pair(p,q)];
    mp[make_pair(p,q)]=0.01*p*(0.01*q/2+0.01*(200.0-q)/2*(solve(p,q+4)+1))+0.01*(100.0-p)*(solve(p,q+3)+1);
    return mp[make_pair(p,q)];
}
int main()
{
    int T;scanf("%d",&T);int TT=0;
    for(int i=1;i<=100;i++)
    {
        int p=i;
        scanf("%d",&p);
        printf("Case %d: %.6f\n",++TT,solve(p,4));
    }
    return 0;
}

打表做:

#include<bits/stdc++.h>
#define mem(a,b) memset((a),b,sizeof(a))
#define de cout<<endl<<endl<<endl
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=100010;
using namespace std;
double ans[110]={0,130.753045,79.205364,61.164050,51.603369,45.502018,41.175611,37.895063,35.290824,33.154035,31.356819,29.815932,28.474488,27.292070,26.239021,25.292991,24.436754,23.656775,22.942244,22.284399,21.676050,21.111233,20.584950,20.092974,19.631705,19.198053,18.789347,18.403267,18.037784,17.691118,17.361696,17.048125,16.749164,16.463705,16.190756,15.929421,15.678896,15.438450,15.207420,14.985205,14.771253,14.565062,14.366172,14.174159,13.988633,13.809236,13.635634,13.467523,13.304615,13.146648,12.993376,12.844569,12.700013,12.559511,12.422874,12.289928,12.160509,12.034465,11.911649,11.791927,11.675170,11.561258,11.450076,11.341518,11.235482,11.131871,11.030594,10.931564,10.834701,10.739926,10.647165,10.556348,10.467408,10.380281,10.294907,10.211227,10.129187,10.048734,9.969817,9.892388,9.816402,9.741813,9.668581,9.596664,9.526025,9.456624,9.388428,9.321402,9.255512,9.190728,9.127018,9.064355,9.002708,8.942053,8.882362,8.823610,8.765774,8.708830,8.652755,8.597528,8.543127};
int main()
{
    int T;scanf("%d",&T);int TT=0;
    while(T--)
    {
        int p;
        scanf("%d",&p);
        printf("Case %d: %.6f\n",++TT,ans[p]);
    }
    return 0;
}

The Tower

题意:给你一个圆锥,然后再给你一个点的位置和它的速度,问经过多长时间它能打到圆锥上,题目数据保证开始时点在圆锥外,并且保证点一定能打到圆锥上。

思路:列除圆锥的表面方程,还有点的参数方程,带入整理解出时间就行了,还挺简单的,主要是不知道圆锥的表面方程,知道的话应该挺简单的。

下面是粗略的计算过程:

代码:

#include<bits/stdc++.h>
#define mem(a,b) memset((a),b,sizeof(a))
#define de cout<<endl<<endl<<endl
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=100010;
using namespace std;
double r,h,xx,yy,zz,vx,vy,vz;
int main()
{
    int T;scanf("%d",&T);int TT=0;
    while(T--)
    {
        scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&r,&h,&xx,&yy,&zz,&vx,&vy,&vz);
        double a,b,c;
        a=vz*vz-h*h*(vx*vx+vy*vy)/(r*r);
        b=2*zz*vz-2*h*vz-h*h*(2*xx*vx+2*yy*vy)/(r*r);
        c=zz*zz+h*h-2*h*zz-h*h*(xx*xx+yy*yy)/(r*r);
        double t1,t2;
        t1=-1*(b+sqrt(b*b-4*a*c))/(2*a);
        t1=-1*(b-sqrt(b*b-4*a*c))/(2*a);
        double t=max(t1,t2);
        printf("Case %d: %.6f\n",++TT,t);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值