php tick,Tick or Tick 时钟问题

一个很绕的计算题

它的意思就是你输入一个角度D,算出三个时针两两之间的角度都要比D大(最小的D),它们才会happy

我们可以通过计算捋一下逻辑:

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

所以相对速度: s_m=59/10°/s,s_h=719/120°/s,m_h=120/11°/s

所以相差一度所需要的时间: sm=10/59 s/°,sh=120/719 s/°,mh=120/11 s/°

他们差360°的周期为: tsm=3600/59 s,tsh=43200/719 s,tmh=43200/11 s

需要相差的角度为D。

至于周期的处理,我们可以从1s开始到1360012s

rsm>D → Dsm+k1tsm < t < tsm-Dsm+k1tsm;

rsh>D → Dsh+k2tsh < t < tsh-Dsh+k2tsh;

rmh>D → Dmh+k3tmh < t < tmh-Dmh+k3tmh;

k1k2k3是用来循环周期的,刚开始不是很明白为什么是 tsm-D*sm

ed4beca0a68c?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

解释啦.png

三个条件都满足所占的总时间即为时针、分针、秒针相差角度大于n的总时间

#include

#include

using namespace std;

int total=12*60*60;

double sm=10/59,sh=120/719,mh=120/11;//相差1°的时间

int main()

{

int t;

double D,max,min;

while(1)

{

int happyTicks=0;

scanf("%lf",&D);

if(D<0)

break;

min=D,max=360-D;

for(int i=0;i

{

if(i<4)

printf("%lf,%lf,%lf\n",sm*double(i),sh*double(i),mh*double(i));

if(min<=sm*double(i)&&sm*double(i)<=max&&min<=sh*double(i)&&sh*double(i)<=max&&min<=mh*double(i)&&mh*double(i)<=max)

happyTicks++;

}

printf("%lf\n",(double)happyTicks/total*100);

}

return 0;

}

但是这么做会超时,然后我就放弃了,去找了discuss

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

所以相对速度s_m=59/10°/s,s_h=719/120°/s,m_h=120/11°/s *

所以相差一度所需要的时间sm=10/59 s/°,sh=120/719 s/°,mh=120/11 s/° *

他们差360°的周期为tsm=3600/59 s,tsh=43200/719 s,tmh=43200/11 s *

需要相差的角度为n。 *

rsm>n → nsm+k1tsm < t < tsm-nsm+k1tsm; *

rsh>n → nsh+k2tsh < t < tsh-nsh+k2tsh; *

rmh>n → nmh+k3tmh < t < tmh-nmh+k3tmh; *

三个条件都满足所占的总时间即为时针、分针、秒针相差角度大于n的总时间 *

#include

void 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(scanf("%lf",&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;

//43200究竟是怎么来的,这三层循环之间是怎么扯上关系的?

//43200是因为只算了12小时,12小时所占的比例就相当于24小时所占的比例

//通过两两是否重合来判断

for(ft3=fmh,et3=emh;et3<=43200;et3+=tmh,ft3+=tmh)

{

for(ft2=fsh,et2=esh;et2<=43200;et2+=tsh,ft2+=tsh)

{

if(et2

continue;

if(ft2>et3)

break;

for(t=0,ft1=fsm,et1=esm;et1<=43200;t=t+1,et1=esm+t*tsm,ft1=fsm+t*tsm)

{

if(et1

continue;

if(ft1>et3 || ft1>et2)

break;

begin=max(ft1,ft2,ft3)

sum+=min-max;

}

}

}

sum/=432.; // 为什么还有除以432?因为要算概率呀sum/43200*100%

printf("%.3lfn",sum);

}

}

#include

#include

#include

#include

using namespace std;

// 秒针速度 s = 6°/s 分针速度 m = 1/10° /s 时针 h = 1/120° /s

const double SH = 719.0/120, SM = 59.0/10, MH = 11.0/120;

const double tSH = 43200.0/719, tSM = 3600.0/59, tMH = 43200.0/11;

double Min(double a,double b,double c)

{

return min(a,min(b,c));

}

double Max(double a,double b,double c)

{

return max(a,max(b,c));

}

int main()

{

double D;

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

{

double bSH,bSM,bMH,eSH,eSM,eMH,Begin,End,Sum = 0;

bSH = D / SH;

bSM = D / SM;

bMH = D / MH;

//计算第一次满足条件的时间(开始时间)

eSH = (360-D)/SH;

eSM = (360-D)/SM;

eMH = (360-D)/MH;

//计算第一次不满足条件的时间(结束时间)

for(double b3 = bSH,e3 = eSH; e3 <= 43200.000001; b3+=tSH,e3+=tSH)

{

for(double b2 = bMH,e2 = eMH; e2 <= 43200.000001; b2+=tMH,e2+=tMH)

{

if(e2 < b3) //判断是否有交集 就是要求有交集

continue; // 判断的话是根据for循环的内外顺序,如果内侧end小于外侧begin还是有机会超过的

if(b2 > e3) //三个循环交换顺序都是可以的

break;

for(double b1 = bSM,e1 = eSM; e1 <= 43200.000001; b1+=tSM,e1+=tSM)

{

if(e1 < b2 || e1 < b3)

continue;

if(b1 > e2 || b1 > e3)

break;

Begin = Max(b1,b2,b3); //开始时间取最大,以满足全部要求

End = Min(e1,e2,e3); //结束时间取最小,以满足全部要求

Sum += (End-Begin);

}

}

}

printf("%.3lf\n",Sum/432);

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值