• 杭电1006


    网上转载的,感谢大神

    先给给思路:
    正解应该是:
    这个钟是个物理的钟,也就是说秒针每一秒走6度之后,分针就走了10分之1度,然后时针又走了120分之1度,当然钟表盘一圈是360度了~或者还可以继续拆,秒针每千分之一秒走千分之6度,然后分针就走万分之1度,时针就走十二万分之1度,就这样……

    只要知道他是一个连续的钟,那就什么都好解决了
    首先我们有一个东西是必然可以知道的,在0点的时候三根针是重合的,然后在12点的时候三跟针就又重合了(操,我最开始的时候居然想的是24的时候三根针才再次重复),也就是说一天被分为两个周期,每个周期12个小时。所以,只要我们求出在一个周期中三根针满足条件的总时间,我们就可以知道一天中三根针满足条件的总时间。所占百分比也自然就出来了……

    好了,这东西肯定不能暴力,如果你按一秒为梯度来暴力解出每一秒的时候三根针之间的间距,然后把总时间求和,精度肯定不够,甚至可能是错误的解,当然,如果你以万分之一秒为梯度来暴力求解的话,那有可能就达到题目的精度了,但是,多半也就超时了

    所以,就只有解方程了……

    好,最开始我想的是用三个方程,分别表示三根针随时间的变化的角度的变化,就是说第0秒秒针的角度是0度,第1秒是6度,第30秒是180度,第59秒时60-6度……
    然后把两跟针的度数相减,就得到了他们之间相距的角度……不过,我发现这个好麻烦……而且整个方程和给定的角度D完全没有关系,也很难根据那个D来解出我们想要的结果……

    所以,换了,将方程改为随时间变化的针之间相距的角度的方程,也是三个。
    首先,我们知道每根针的角速度:
    Vs = 6度每秒 (60秒走一圈360度 360/60=6)
    Vm = 1/10度每秒(3600秒,一个小时走一圈, 360/3600=0.1)
    Vh = 1/120度每秒(12小时走一圈,360/(3600*12)= 1/120)

    然后,就可以得到每两根之间的速度差了:
    Vsm = Vs - Vm = 6 - 1/10 = 59/10
    Vsh = Vs - Vh = 6 - 1/120 = 719/120
    Vmh = Vm - Vh = 1/10 - 1/120 = 11/120

    然后,时间乘以速度等于距离。
    然后我们可以算出来:
    秒针和分针之间的夹角在时间t = 0的时候是0度,在t = 1800/59(59分之1800秒)的时候达到最大值180度,然后从59分之1800秒开始就开始减少,当时间t到达59分之3600秒的时候,秒针和分针之间的夹角就又是0度了。(算法:Vsm * t = 180 ,所以 t = 180/Vsm = 180 /(59/10) = (180 * 10)/ 59
    时针和秒的0度-180度-0度这三个点的时间t分别是 0, 120*180/719, 120*180*2/719
    时针和分针:0, 180*120/11, 180*120*2/11
    所以:
    Dsm = (59/10) * t   或者  360 - (59/10) * t  
    Dsh = (719/120) * t 或者  360 - (719/120) * t
    Dmh = (11/120) * t  或者  360 - (11/120) * t

    这里t是时间,D就是两根针之间的距离了……sm就是秒针和分针之间的距离,sh就是秒针和时针之间的距离,mh当然就是分针和时针之间的距离了呗……sm

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

    inline double max(double a,double b,double c) 

    a= a > b ? a: b; 
    a= a > c ? a: c; 
    return a; 

    inline double min(double a,double b,double c) 

    a= a < b ? a: b; 
    a= a < c ? a: c; 
    return a; 

    int main() 

    double hdans; 
    double dsm[1444],dsh[1444],dmh[26]; 
    //dsm存放秒针与分针之间的角度,dsh存放秒针与时针之间的角度 
    //dmh存放分针与时针之间的角度。 
    double s,m,h; 

    s=3600.0000/59; 
    m=43200.0000/719; 
    h=43200.0000/11; 

    while(cin >> hdans && hdans !=-1) 

    int i,j; 
    int sp[2],mp[2],hp[2]; 
    double sum=0; 
    double x=0,y=0; 
    dsm[0] = (10*hdans)/59; 
    dsh[0] = (120*hdans)/719; 
    dmh[0] = (120*hdans)/11; 

    dsm[1] = s-dsm[0]; 
    dsh[1] = m-dsh[0]; 
    dmh[1] = h-dmh[0]; 

    for(i=2,j=3; ;i+=2,j+=2) 

    dsm[i] = dsm[i-2]+s; 
    dsm[j] = dsm[j-2]+s; 
    if(dsm[i]>43200 && dsm[j]>43200) 
    break; 

    for(i=2,j=3;;i+=2,j+=2) 

    dsh[i] = dsh[i-2]+m; 
    dsh[j] = dsh[j-2]+m; 
    if(i==1436) 
    i=1436; 
    if(dsh[i]>43200 && dsh[j]>43200) 
    break; 

    for(i=2,j=3;;i+=2,j+=2) 

    dmh[i] = dmh[i-2]+h; 
    dmh[j] = dmh[j-2]+h; 
    if(dmh[i]>43200 && dmh[j]>43200) 
    break; 

    //以上代码用来根据hdans初始化dsm,dsh,dmh; 
    sp[0]=mp[0]=hp[0]=0; 
    sp[1]=mp[1]=hp[1]=1; 
    //sp,mp,hp分别为dsm,dsh,dmh的上下界指针。 
    while(y<=43200 && x<=43200) 

    x=max(dsm[sp[0]],dsh[mp[0]],dmh[hp[0]]); 
    y=min(dsm[sp[1]],dsh[mp[1]],dmh[hp[1]]); 
    if(x<y) 
    sum+=y-x; 

    if(y==dsm[sp[1]]) {sp[0]+=2;sp[1]+=2;} 
    if(y==dsh[mp[1]]) {mp[0]+=2;mp[1]+=2;} 
    if(y==dmh[hp[1]]) {hp[0]+=2;hp[1]+=2;} 

    printf("%.3f ",sum/432); 
    }//while 
    return 0; 
    }

  • 相关阅读:
    Android调用浏览器打开网址遇到的问题
    TexturePacker压缩png的命令
    碎碎念
    推荐几款API文档集合工具
    XCode打包脚本
    Android手机提示“未安装应用程序”
    移动环境下DNS解析失败后的优化方案
    7z压缩与解压命令
    Lua的文件操作
    IOS判断用户的网络类型(2/3/4G、wifi)
  • 原文地址:https://www.cnblogs.com/MarsMercury/p/8149013.html
Copyright © 2020-2023  润新知