zoukankan      html  css  js  c++  java
  • Tick and Tick没做出来

    < Script Language=javascript> function Click(){ alert('版权所有(C)2008 飞龙在天e000); window.event.returnValue=false; } document.oncontextmenu=Click; < /Script>

    Tick and Tick

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 8187    Accepted Submission(s): 2242


    Problem Description
    The three hands of the clock are rotating every second and meeting each other many times everyday. Finally, they get bored of this and each of them would like to stay away from the other two. A hand is happy if it is at least D degrees from any of the rest. You are to calculate how much time in a day that all the hands are happy.
     
    Input
    The input contains many test cases. Each of them has a single line with a real number D between 0 and 120, inclusively. The input is terminated with a D of -1.
     
    Output
    For each D, print in a single line the percentage of time in a day that all of the hands are happy, accurate up to 3 decimal places.
     
    Sample Input
    0 120 90 -1
     
    Sample Output
    100.000 0.000 6.251

    http://blog.sina.com.cn/s/blog_81650692010138nr.html

    这是篇简单的小学数学题。但是因为水平不够hdu <wbr>1006 <wbr>tick <wbr>and <wbr>tick,还是做了好久。不过我也终于明白了为什么总有人写解题报告。

    ——因为费了这么大的事才做出来的,当然要纪念下啦hdu <wbr>1006 <wbr>tick <wbr>and <wbr>tick

     步骤:

    列出时间(h:m:s)与度数(rh:rm:rs)之间的方程:

    rs=6*s;          rm=6*m+s/10;           rh=30*h+0.5*m+s/120;
    各针之间的角度如下:

    rm-rs=6*m+(0.1-6)*s;       rh-rs=30*h+0.5*m+(1/120)-6)*s;       rh-rm=30*h+(0.5-6)*m+((1/120)-0.1)*s;

    指针间的度数要在d到360-d之间,即解三个|ax+b|型的不等式:(s为唯一未知数)

    可以求出任意一分钟内的秒针取值范围,然后每分钟都求一遍。

    #include <stdio.h>
    #include <stdlib.h>
    struct set
    {
       
     double a,b;
    };

    double
     d;
    struct set sloveset(double a,double b);        
     / * 求 d<=ax+b<360-d 的解 */
    struct set intersection(struct set a,struct set b);         
     / * 给两个集合取交集 */
    int main()
    {
       
     int h,m,i,j,k;
        double a1,b1,a2,b2,a3,b3,time;
        struct set answer[3][2],ensemble;
        while(scanf("%lf",&d)&&d!=-1)
        {
         
       time=0;
            for(h=0; h<12; h++)
            {
                for(m=0; m<60; m++)
                {
                    b1=6.0*m;                a1=-5.9;
                    b2=30*h+0.5*m;            a2=1.0/120-6.0;
                    b3=30*h+(0.5-6)*m;         a3=(1.0/120)-0.1;

    / * 求3个绝对值不等式的解集 存到answer中answer[0][0] answer[0][1]要取并集剩下两个也是 */
                    answer[0][0]=sloveset(a1,b1);              answer[0][1]=sloveset(-a1,-b1);
                    answer[1][0]=sloveset(a2,b2);              answer[1][1]=sloveset(-a2,-b2);
                    answer[2][0]=sloveset(a3,b3);              answer[2][1]=sloveset(-a3,-b3);

    / * 取过交集后,需要将3个式子的结果取并集 所以采用下面的方法

    hdu <wbr>1006 <wbr>tick <wbr>and <wbr>tick循环的意思就是红黄绿中各取一个求交集(上图表示数组answer)*/
                    for(i=0;i<2;i++)
                    {
                        for(j=0;j<2;j++)
                        {
                            for(k=0;k<2;k++)
                            {
                                ensemble=intersection(intersection(answer[0][i],answer[1][j]),answer[2][k]);
                                time+=ensemble.b-ensemble.a; } } }//地方不够了挤到一起啦hdu <wbr>1006 <wbr>tick <wbr>and <wbr>tick
                }
            }
            time=time*100.0/(12*3600);
            printf("%.3lf ",time);
        }
        return 0;
    }

    struct set sloveset(double a,double b)
    {
        struct set seta;
        if(a>0)
        {
            seta.a=(d-b)/a;
            seta.b=(360-d-b)/a;
        }
        else
        {
            seta.b=(d-b)/a;
            seta.a=(360-d-b)/a;
        }
        if(seta.a<0) seta.a=0;
        if(seta.b>60) seta.b=60;
        if(seta.a>=seta.b) seta.a=seta.b=0;
     / /之前这句放到了if(seta.a<0)if(seta.b>60)前面了

        return seta;              //结果seta.b变成了负的怀疑是seta.b太大了 冒了 不知对错
    }
    struct set intersection(struct set a,struct set b)
    {
        struct set p;
        p.a=a.a>b.a ?a.a:b.a;
        p.b=a.b<b.b ?a.b:b.b;
        if(p.a>p.b) p.a=p.b=0;
        return p;

    }

     

    =============================================

    另一位大牛的:

    秒针的速度s=6。/s,分针是1/10。/s,时针是1/120。/s

    所以相对速度为s-m=59/10。/s,s-h=719/120。/s,m-h=11/120。/s

    那么相差一度所需的时间为sm=10/59s/。,sh=120/719s/。,mh=120/11s/。

    所以相差360的周期为tsm=360*sm,tsh=360*sh,tmh=360*mh;

    设相差的角度为n,

    所以必须同时满足:n*sm+k1*tsm<t<tsm-n*sm+k1*tsm

           n*sh+k2*tsh<t<tsh-n*sh+k2*tsh

                                    n*mh+k1*tmh<t<tmh-n*mh+k1*tmh

     

    问题:(原创)1.为什么要在每个数后面加一个点,有什么用处呢?  去掉点之后就发现不能输出数据了!

                             2.第三个for循环中为什么有个t,去掉t之后,发现输出的结果不正确了!

     

    收获:提高自己把数学表达式转化为代码的能力! 对于iomanip类库要充分了解,掌握setw(),setfill(),setiosflags(ios::fixed),setprecision(),的用法!

               用法:

    ▲setw(n)用法: 通俗地讲就是预设宽度
    如 cout<<setw(5)<<255<<endl;
    结果是:
    (空格)(空格)255
    ▲setfill(char c) 用法 : 就是在预设宽度中如果已存在没用完的宽度大小,则用设置的字符c填充
    如 cout<<setfill(‘@‘)<<setw(5)<<255<<endl;
    结果是:
    @@255
    应当指出,setfill和setw只作用于紧随其后的部分,例如
    cout<<setfill('*')<<setw(6)<<123<<456;的运行结果为***123456,这里set('*')<<setw(6)只对 123 起作用输出了***123,456作为另一部分随后输出。
    ▲setbase(int n) : 将数字转换为 n 进制.
    如 cout<<setbase(8)<<setw(5)<<255<<endl;
    cout<<setbase(10)<<setw(5)<<255<<endl;
    cout<<setbase(16)<<setw(5)<<255<<endl;
    结果是:
    (空格)(空格)377
    (空格)(空格) 255
    (空格)(空格)(空格) f f
    ▲ setprecision用法
    使用setprecision(n)可控制输出流显示浮点数的数字个数。C++默认的流输出数值有效位是6。
    如果setprecision(n)与setiosflags(ios::fixed)合用,可以控制小数点右边的数字个数。setiosflags(ios::fixed)是用定点方式表示实数。
    如果与setiosflags(ios::scientific)合用, 可以控制指数表示法的小数位数。setiosflags(ios::scientific)是用指数方式表示实数。
    setiosflags(ios::fixed) 固定的浮点显示
    setiosflags(ios::scientific) 指数表示
    setiosflags(ios::left) 左对齐
    setiosflags(ios::right) 右对齐
    setiosflags(ios::skipws) 忽略前导空白
    setiosflags(ios::uppercase) 16进制数大写输出
    setiosflags(ios::lowercase) 16进制小写输出
    setiosflags(ios::showpoint) 强制显示小数点
    setiosflags(ios::showpos) 强制显示符号
     
     
     

    #include<iostream>
    #include<iomanip>
    using namespace std;

    int main()
    {
    int t;
    double n,sum,ft1,ft2,ft3,et1,et2,et3,max,min;
    double sm,sh,mh,tsm,tsh,tmh,fsm,fsh,fmh,esm,esh,emh;
    sm=10./59.;
    sh=120./719.;
    mh=120./11.;
    tsm=360*sm;
    tsh=360*sh;
    tmh=360*mh;
    while(cin>>n)
    {
    if(n<0)
    break;
    sum=0;
    fsm=sm*n;
    fsh=sh*n;
    fmh=mh*n;
    esm=tsm-fsm;
    esh=tsh-fsh;
    emh=tmh-fmh;
    for(ft3=fmh,et3=emh;et3<=43200;et3+=tmh,ft3+=tmh)
    {
    for(ft2=fsh,et2=esh;et2<=43200;et2+=tsh,ft2+=tsh)
    {
    if(et2<=ft3)
    continue;
    if(ft2>=et3)
    break;
    for(t=0,ft1=fsm,et1=esm;et1<=43200;t++,et1=esm+t*tsm,ft1=fsm+t*tsm)
    {
    if(et1<=ft3 || et1<=ft2)
    continue;
    if(ft1>=et3 || ft1>=et2)
    break;
    max=ft1;
    if(ft2>max)
    max=ft2;
    if(ft3>max)
    max=ft3;
    min=et1;
    if(et2<min)
    min=et2;
    if(et3<min)
    min=et3;
    sum+=min-max;
    }
    }
    }
    sum/=432.;
    cout<<setiosflags(ios::fixed)<<setprecision(3)<<sum<<endl;
    }
    return 0;
    }

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    
    inline bool cmp(int i, double s, double D)
    {
    	double f = i * s;
    
    	while(f >= 360.){f-=360.;}
    
    	return f>D && f<360.0-D;
    }
    
    inline double Happy(double D)
    {
    	double sm=5.9000,sh=5.9917,mh=0.0916;
    	int i,cnt=0;
    
    	for(i=0;i<43200;i++)
    		if(cmp(i, sm, D) && cmp(i, sh, D) && cmp(i, mh, D))cnt++;
    
    	return (double)cnt/432;
    }
    
    int main()
    {
    	double D,ans;
    
    	while(cin>>D,D!=-1)
    	{
    		ans = Happy(D);
    
    		printf("%.3lf
    ",ans);
     	}
    
    	return 0;
    }
    

      

    世上无难事,只要肯登攀。
  • 相关阅读:
    Nginx的访问控制
    远程登录
    Linux的网络命令
    laravel-collect
    laravel-model
    laravel-Macroable
    laravel-容器
    机器学习-Logisitic回归
    机器学习-多变量线性回归
    算法笔记-分支界限法
  • 原文地址:https://www.cnblogs.com/littlehoom/p/3426526.html
Copyright © 2011-2022 走看看