ACM题解报告——HD1006

  

  今天解了一道杭电上的1006题:http://acm.hdu.edu.cn/showproblem.php?pid=1006

  题目的大体意思就是讲,时钟上的时针、分针、秒针都想远离彼此,当三种针间的角度差都至少是给定的D角度时,称为happytime,最后需要输出一天内happytime所占的比例。解决该题的基本思想就是进行12小时即720分钟的happytime的暴力搜索,算出的总秒数除以720*60即最后的比例。

  1、最开始拿到这个问题的时候,感觉有点无从下手,因为三种针每秒都在动着,我们可以选择一个标准,就是12时为0度,三种针的角速度都可以求出:时针:1/120 度/秒,分针:0.1 度/秒,秒针:6 度/秒,那么假使此刻为h时m分s秒,时针、分针、秒针的角度分别为30*h+0.5*m+1/120*s、6*m+0.1*s、6*s。

  2、按照题目的意思,会给定一个角度D,而三种针两两之间的角度差必须要大于D,也就是解不等式

D<|angle|<360-D,分别解出不等式,再求它们之间的交集。

#include<stdio.h>
#include<stdlib.h>

/*h时m分s秒这一时刻的时针、分针、秒针的角度  */
#define hangle 30*h+0.5*m+1/120*s
#define mangle 6*m+0.1*s
#define sangle 6*s

/*三种针的转速*/
#define vh 1.0/120
#define vm 0.1
#define vs 6.0

int degree;
int s=0;

typedef struct //定义一个结构体用于储存不等式的解
{
  double l;
  double r;
}second;

second bargin(second a,second b)
{//函数bargin求交集
  second c;
 if(a.l>b.l )
  c.l=a.l;
 else
   c.l=b.l;
 if(a.r<b.r)
   c.r=a.r;
 else
   c.r=b.r;
 if(c.l>=c.r )
   c.r=c.l=0;
 return c;
}
second solve(double diff,double angle )
{//解不等式degree<|s*diff+angle|<360-degree
  second ln;
if( diff>0 )
{
  ln.l=(degree-angle)/diff;
 ln.r=(360-degree-angle )/diff;
 }
 else
{
 ln.l=(360-degree-angle )/diff;
 ln.r=( degree-angle)/diff;
 }
if( ln.l<0 )
  ln.l=0;
if( ln.r>60 )
  ln.r=60;
if( ln.r<=ln.l )
  ln.r=ln.l=0;

 return ln;
}

double happytime(int h,int m )
{
  second  ss[3][2];
  double diff,angle;
  second ln;
  double result=0.0;
  //hm  时针与分针之间满足happytime的秒数
  diff=vh-vm;
 angle=hangle-mangle;
  ss[0][0]=solve( diff,angle );
  ss[0][1]=solve( -diff,-angle );

  //hs    时针与秒针之间满足happytime的秒数
  diff=vh-vs;
  angle=hangle-sangle;
  ss[1][0]=solve( diff,angle );
 ss[1][1]=solve(-diff,-angle );

 //ms    分针与秒针之间满足happytime的秒数
  diff=vm-vs;
  angle=mangle-sangle;
ss[2][0]=solve( diff,angle );
ss[2][1]=solve(-diff,-angle );
 int k,p,n;
/*注意下面这里的思想,绝对值不等式解出的区间要取并集,例如ss[0][0]与ss[0][1]间取并;而三个不同的表达式之间要取交集,即                       ss[0][]与ss[1][]之间要取交集的 */
 for( k=0;k<2;k++ )
   for( p=0;p<2;p++ )
     for( n=0;n<2;n++ )
{
  ln=bargin( bargin(ss[0][k],ss[1][p]),ss[2][n] );
  result+=( ln.r-ln.l );
 }
 return result;//返回每分钟内的happytime秒数
}
int main()
{
  int h,m;

  while(scanf("%ld",&degree)&&degree!=-1 )//输入-1结束
{
  double result=0;
  for(h=0;h<12;h++ )
    for(m=0;m<60;m++ )
{
  result+=happytime( h,m );
 }
  printf( "%.3lf\n",result*100.0/43200 );//最后的结果是输出比例
 }
  return 0;
}

杭电测试通过

原文地址:https://www.cnblogs.com/paradises/p/3051419.html