几个比较简单的题,但是。。。。。

时间:2021-09-25 17:35:30
A - 18岁生日
Gardon的18岁生日就要到了,他当然很开心,可是他突然想到一个问题,是不是每个人从出生开始,到达18岁生日时所经过的天数都是一样的呢?似乎并不全都是这样,所以他想请你帮忙计算一下他和他的几个朋友从出生到达18岁生日所经过的总天数,让他好来比较一下。 
 

Input

一个数T,后面T行每行有一个日期,格式是YYYY-MM-DD。如我的生日是1988-03-07。 
 

Output

T行,每行一个数,表示此人从出生到18岁生日所经过的天数。如果这个人没有18岁生日,就输出-1。
 
主要是考虑闰年的2月会有29号,一般人的18岁会经历4个闰年(闰年的判断条件是能被4整除,不能被100整除,后者可以被400整除,一般情况下4年一个轮回),所以先计算出一般人的天数,然后判断当他出生那年是否为闰年,并且是否在2月及以前出生,是则加1,然后判断18岁那年是否为闰年,并且生日在2月以后,是则加1,除了这两个还有两种情况,当他1岁那年是闰年,那么他17岁的时候也是闰年,会经历5个闰年,也要加1,还有最后一种情况就是,他的0到18岁中途只有三个闰年的,例如他是1885年出生的,其中经历的1900年不是闰年,他总共只经历了3个闰年,但是最初计算的一般值是有4个闰年,所以要减1.
 
#include <iostream>
#include<cstdio>
using namespace std;


int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int year,mon,day;
        scanf("%d-%d-%d",&year,&mon,&day);
        int alld=18*365+4;                      //一般情况下的总数
        if((year%4==0&&year%100!=0)||year%400==0)
        {
            if(mon<=2)
            {
                if(mon==2&&day==29)
                    {printf("-1\n");
                     continue;}
                else alld+=1;
            }
        }
        else{
                if(year%4==3) alld+=1;
        else{
        int y=year+18;
        if((y%4==0&&y%100!=0)||y%400==0)
        {
            if(mon>2)
                alld+=1;
        }
        }
        }
        if(year%100>82&&year%400<382) alld-=1;         //他的18年中(除去出生那年和18那年)包含有能被4整除的不是闰年的情况
        printf("%d\n",alld);
    }
    return 0;
}


E - 圆有点挤
gg最近想给女友送两个精美的小礼品:两个底面半径分别为R1和R2的圆柱形宝石,并想装在一个盒子里送给女友。好不容易找到了一个长方体的盒子,其底面为A*B的矩形,他感觉好像宝石装不进去,但又不敢轻易塞进去试试。现请你帮他判断两个宝石能否放进盒子里(宝石只能竖直放置,且不能堆叠)。

Input

输入的第一行是一个整数,为数据的组数t(t<=1000)。

每组数据占一行,包括4个数A,B,R1,R2,均为不超过1e4的正整数。

Output

对于每组数据,若两个宝石能放进盒子中,则输出YES,否则输出NO。

我最初想到的就是建坐标系,长为a,宽为b,大圆半径为r1,小圆半径为r2,把两个圆都紧靠着矩形的两个对角,大圆圆心的坐标为(r1,r1),小圆圆心坐标为(a-r2,b-r2),然后求两个圆心之间的距离是否大于两个圆的半径之和,大于等于则说明可以放进去。做的时候考虑太多东西了,结果一直没做出来,简直是郁闷,最后不考虑之前的,只考虑了两个圆单独放是否能放进去就可以了,也就是两个圆的直径都要小于矩形的长和宽。
#include <iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;


int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int a,b,r1,r2;
        scanf("%d%d%d%d",&a,&b,&r1,&r2);
        if(a<b) swap(a,b);
        if(r1<r2) swap(r1,r2);
        if(2*r1>b)
        {
            printf("NO\n");
            continue;
        }
        int x=b-r2-r1,y=a-r1-r2;
        int z=r1+r2;
        if(x*x+y*y>=z*z) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

G - 开门人和关门人
每天第一个到机房的人要把门打开,最后一个离开的人要把门关好。现有一堆杂乱的机房签  到、签离记录,请根据记录找出当天开门和关门的人。 
 

Input

测试输入的第一行给出记录的总天数N ( > 0 )。下面列出了N天的记录。  每天的记录在第一行给出记录的条目数M ( > 0 ),下面是M行,每行的格式为  证件号码 签到时间 签离时间  其中时间按“小时:分钟:秒钟”(各占2位)给出,证件号码是长度不超过15的字符串。 
 

Output

对每一天的记录输出1行,即当天开门和关门人的证件号码,中间用1空格分隔。  注意:在裁判的标准测试输入中,所有记录保证完整,每个人的签到时间在签离时间之前,  且没有多人同时签到或者签离的情况。 
 
刚做的时候想的是把签到和签退的时间都分时,分,秒,分别记录在一个结构体中,然后排序的时候先按签到的时排序,然后再对时相等的按分排序,再同样对秒排序,最后输出第一位名字,然后同样对签退时间按大到小排序,输出第一位名字,后来知道了一种比较简单的方法,直接用strcmp比较字符串的大小,因为他时间的格式都是一样的,所以可以直接比较。strcmp(a,b)表示a和b字符串相比较,返回a中的字符 与b中字符 的ASCLL码的差值。
 
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct cheak
{
    char name[20],in[20],out[20];
}c[10000];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%s%s%s",c[i].name,c[i].in,c[i].out);
        }
        for(int i=0;i<n;i++)
        {
            struct cheak t;
            int xx=strcmp(c[0].in,c[i].in);
            if(xx>0)
            {
                t=c[i];
                c[i]=c[0];
                c[0]=t;
            }
        }
        printf("%s ",c[0].name);
        for(int i=0;i<n;i++)
        {
            struct cheak t;
            int yy=strcmp(c[i].out,c[0].out);
            if(yy>0)
            {
                t=c[i];
                c[i]=c[0];
                c[0]=t;
            }
        }
        printf("%s\n",c[0].name);
    }
    return 0;
}