您的位置:首页 > 其它

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

2015-12-06 11:13 141 查看
A - 18岁生日
Gardon的18岁生日就要到了,他当然很开心,可是他突然想到一个问题,是不是每个人从出生开始,到达18岁生日时所经过的天数都是一样的呢?似乎并不全都是这样,所以他想请你帮忙计算一下他和他的几个朋友从出生到达18岁生日所经过的总天数,让他好来比较一下。  Input一个数T,后面T行每行有一个日期,格式是YYYY-MM-DD。如我的生日是1988-03-07。  OutputT行,每行一个数,表示此人从出生到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;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: