HDU4530

HDU4530Q系列故事——大笨钟

Time Limit: 600/200 MS(Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 977    Accepted Submission(s): 506

Problem Description

  饱尝情感苦恼的小Q本打算隐居一段时间,但仅仅在3月25号一天没有出现,就有很多朋友想念他,所以,他今天决定再出来一次,正式和大家做个告别。
  
  小Q近来睡眠情况很差——晚上睡不着,早上又起不来!以前总是全勤的他这个月甚至迟到了好几次,虽然主管没说什么,但是他自己清楚此事的严重性。
  爱情没有了,小Q不想再失去面包,于是他决定买个闹钟,为求质量可靠,特意挑了个最贵的原装进口货!但是,正所谓屋漏偏逢连夜雨、人倒霉的时候喝凉水都塞牙,小Q新买的这个进口闹钟竟然每分钟总是比正确时间慢那么几秒!
  可怜的小Q愤愤然道:“真是一个大笨钟!”
  但是为了充分利用大笨钟,小Q还是尽力想办法搞清楚它的性能,希望能将其当作正常时钟使用。
  小Q从如下三方面去研究大笨钟:
  1、 假设正常时间走了t分钟,计算大笨钟走的时间;
  2、 假设大笨钟走了t分钟,计算正常时间走的时间;
  3、 小Q将大笨钟与当前时间调成正确时间,此时记为第0次,计算第k次大笨钟显示的时间与正确时间相同需要的时间(大笨钟的结构和普通时钟相同,即分为12大格,60小格)。

Input

输入数据第一行是一个正整数T,表示总共有T组测试数据;
接下来的每组数据首先输入正整数x,表示大笨钟每分钟比正常时钟慢x秒;
接下来一行是一个正整数Q,表示共有Q次询问;
接下来Q行,每行首先输入询问方式(1、2或3,对应小Q研究大笨钟的三方面),如果输入1或2,接下来输入正整数t,如果输入3,接下来输入正整数k(t和k的含义见题目)。
[Technical Specification]
T <= 100
x < 60
Q <= 100
t <= 10000
k <= 10

Output

请输出要计算的答案,以秒为单位,保留两位小数,每次查询输出一行(参见Sample)。

Sample Input

1

1

3

1 2

2 2

3 1

Sample Output

118.00

122.03

2592000.00

Hint

小Q最后还想说句话:“进口货未必可靠,咱们还是支持国货吧!”

 Source

2013腾讯编程马拉松复赛第一场(329日)

分析:大笨钟每分钟比正常时钟慢X正常钟秒,那么大笨钟每分钟要走(60+x)秒,大笨钟每秒要走实际时间的(60+x)/60秒。对于三种情况如下:

1.       正常钟走了t分钟,大笨钟走了t*60*60/(60+x)秒。

2.       大笨钟走了t分钟,正常钟走了t*(60+x)秒。

3.       想象一个胖子和一个瘦子在同一个圆圈跑到跑步,同时开始,那么瘦子(跑得快)必然会一次又一次的和胖子在跑道上会和。

大笨钟走了一圈(24小时)的时间为:

c1 =3600*12*(60+x)/60 秒

正常钟走了一圈的时间为:

c2 =3600*12 秒

大笨钟和正常钟重合(设重合时大本钟和正常钟都显示在走了z秒的时刻),大笨钟走了a1圈,正常钟走了a2圈(a1<a2)则有:(由于两个钟走的总现实时间是一样的)

c1*a1+z*(60*x)/60 = c2*a2+z

简化为:c1*a1+x/60*z=c2*a2

a2从1圈开始,a1从0开始到a2-1,求出z即可,要求0<=Z<3600(z=3600时实际上就是下一圈的事了)。

代码:

#include<cstdio>
using namespace std;
#define c1 60.0*12.0*(60.0+(x))
#define c2 3600.0*12.0
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        double x;
        scanf("%lf",&x);
        int q;
        scanf("%d",&q);
        while(q--)
        {
            int type;
            double t;
            int k;
            scanf("%d",&type);
            if(type==1)
            {
                scanf("%lf",&t);
               printf("%.2lf\n",t*60.0*60.0/(60.0+x));
            }
            else if(type==2)
            {
                scanf("%lf",&t);
               printf("%.2lf\n",t*(60+x));
            }
            else if(type==3)
            {
                scanf("%d",&k);
                if(k==0)
                {
                    printf("0.00\n");
                    continue;
                }
                int ans=0;
                double a1,a2,z;
 
                //printf("%lf%lf\n",c1*1.0,c2*1.0);
                for(a2=1.0;;a2++)
                {
                    for(a1=0.0;a1<a2;a1++)
                    {
                        z=(c2*a2-c1*a1)*60/x;
                       if(z>=0.0&&z<3600)
                        {
                            ans++;
                            if(ans==k)break;
                        }
                    }
                    if(ans==k)break;
                }
               printf("%.2lf\n",a2*c2+z);
            }
        }
    }
    return 0;
}

以上解法理解题意有偏差。

原题本意是:大笨钟每分钟比正常时钟慢X大笨钟秒。即当大笨钟走到60-x秒时,已经过了1分钟。所以大笨钟每秒等于正常时间的60/(60-x)秒。

1.       正常钟t分钟,大笨钟为 t *( 60 – x )秒。

2.       大笨钟t分钟,正常钟为t*60*60/(60-x)秒。

3.       大笨钟走一圈要c1=12.0*3600.0*60/(60-x)秒

正常钟走一圈要c2=12.0*3600.0 秒

假设大笨钟的指针和正常钟的指针在同一时刻在同一圆圈开始走,大笨钟每走一圈,正常钟要比它多走(c1-c2)/c2圈。当正常钟比大笨钟正好多走1圈,2圈,3圈,…k圈的时候,他们分别是第1次,2次,3次,…k次相遇。

则当大笨钟每多走1圈的时候,正常钟多走了c1/c2圈。即正常钟多走了1+(c1-c2)/c2圈。则第k次相遇时的正常时间为:k*c1/( (c1-c2)/c2 )秒。化简结果为:k*12.0*3600.0*60.0/x秒

#include<cstdio>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)//实例个数
    {
        double x;
        scanf("%lf",&x);//大笨钟慢的x秒
        int q;
        scanf("%d",&q);//查询个数
        while(q--)
        {
            int type;
            double t;
            scanf("%d",&type);//查询类别
            if(type==1)
            {
                scanf("%lf",&t);
                printf("%.2lf\n",t*(60-x));//1类
            }
            else if(type==2)
            {
                scanf("%lf",&t);
                printf("%.2lf\n",t*60*60/(60-x));//2类
            }
            else if(type==3)
            {
                scanf("%lf",&t);
                printf("%.2lf\n",t*12.0*3600.0*60.0/x);//根据计算得出的简化结果
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值