hdu1006

本文详细介绍了如何通过编程方法计算时钟指针间的角度变化,并求解任意时间点下指针之间的可能角度范围。利用数学公式与编程实现,实现了对时钟指针状态的精确分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

步骤:

列出时间(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>
#include<math.h>

/*定义区间的上下限*/
typedef struct Extent
{
double l,r;
}extent;
double degree;
/*需要degree<|ax + b |<360-dgree即可解不等式*/
extent method(double a,double b)
{
extent  p;
if(a > 0)
{
p.l = (degree - b)/a;
p.r = (360 - degree - b)/a;
}
else if(a < 0)
{
p.r = (degree - b)/a;
p.l = (360 - degree - b)/a;
}
if(p.l < 0)
{
p.l = 0;
}
if(p.r > 60)
{
p.r = 60;
}
if(p.l >= p.r)
{
p.l = p.r = 0;
}
return p;
}

/*求最大值*/
double max(double a,double b)
{
return a > b ?a:b;
}

/*求最小值*/
double min(double a,double b)
{
return a < b?a:b;
}

/*求交集*/
extent mixed(extent p1,extent p2)
{
extent p;
p.l = max(p1.l,p2.l);
p.r = min(p1.r,p2.r);
if(p.l >= p.r)
{
p.l = p.r = 0;
}
return p;
}

double happytime(int h,int m)
{
extent s[3][2];/*用来保存不等式的解*/
extent x;/*保存交集*/
double a1,a2,a3;
double b1,b2,b3;
a1 = 1/120.0 - 1 /10.0,b1 = h * 30.0 + m /2.0 - m * 6.0;/*hw - mw得到的a1x+b1*/
a2 = 1/120.0 - 6.0,b2 = h * 30.0 + m /2.0;/*hw - sw得到的a2x+b2*/
a3 = 6.0 - 0.1,b3 = -1*m*6.0;/*sw - mw得到的a3x+b3*/
s[0][0] = method(a1,b1);/*s[0]保存不等式degree<|a1x+b1|<360-degree的解*/
s[0][1] = method(-a1,-b1);
s[1][0] = method(a2,b2);/*s[1]保存不等式degree<|a2x+b2|<360-degree的解*/
s[1][1] = method(-a2,-b2);
s[2][0] = method(a3,b3);/*s[2]保存不等式degree<|a3x+b3|<360-degree的解*/
s[2][1] = method(-a3,-b3);

/*然后再s[0],[s1],s[2]中找交集*/
/*把三个不等式的解每次那一个出来,一共有8个交集,把这八个交集的值再并起来,就是把交集区间的值都加起来就是这一分钟的*/                
       /*happy时间*/
double sum = 0.0;/*保存最终结果*/
for(int i = 0;i < 2;++i)
{
for(int j = 0;j < 2;++j)
{
for(int k = 0;k < 2;++k)
{
x = mixed(mixed(s[0][i],s[1][j]),s[2][k]);
sum += (x.r - x.l);
}
}
}
return sum;
}
 

int main()
{
int h,m;
double count;
while(1)
{
count = 0.0;
scanf("%lf",&degree);
if(degree == -1)
{
break;
}
for(h = 0;h < 12;++h)
{
for(m = 0;m < 60;++m)
{
count += happytime(h,m);
}
}
printf("%.3lf\n",count/432.0);
}
return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值