HDU1006 Tick and Tick

题目链接:https://vjudge.net/problem/HDU-1006

题目大意:

  给定一个\(D\),问时钟上时针、分针、秒针之间的角度差都大于或等于\(D\)的概率是多少。

知识点:  暴力

解题思路:

  枚举时与分,对于每一分钟,设秒数为\(s\),由时、分、秒可以推出各针当前的角度。任意两针之间的角度差大于等于\(D\)小于等于\((360-D)\),由这条关系可以推出三条不等式,求出关于\(s\)的三个区间,\(s\)在这一分钟的合法区间即为这三个区间的交集。

AC代码:

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 const double ex = 1e-8;
 5 double D;
 6 struct Range{
 7     double l,r;
 8 }t[10];
 9 Range six;  //[0,60]
10 Range jiao(Range a,Range b){    //求两个区间的交区间
11     Range ret;
12     if(a.r<=b.l||b.r<=a.l)    ret.l=ret.r=-1.0; //空集
13     else
14         ret.r=min(a.r,b.r),ret.l=max(a.l,b.l);
15     return ret;
16 }
17 void cal(double a,double b,int ind){
18     t[ind].l=(D-b)/a,t[ind].r=(360.0-D-b)/a;
19     t[ind]=jiao(t[ind],six);
20     ind++;
21     t[ind].l=-(360.0-D+b)/a,t[ind].r=-(D+b)/a;
22     t[ind]=jiao(t[ind],six);
23 }
24 double finds(int hour,int mint){
25     cal(11.0/120.0,11.0/2.0*mint-30.0*hour,0);
26     cal(6.0-1.0/120.0,-0.5*mint-30.0*hour,2);
27     cal(6.0-0.1,-6.0*mint,4);
28     Range tmp;
29     double ret=0;
30     for(int i=0;i<2;i++){
31         for(int j=2;j<4;j++){
32             for(int k=4;k<6;k++){
33                 tmp=jiao(jiao(t[i],t[j]),t[k]);
34                 ret+=(tmp.r-tmp.l);
35             }
36         }
37     }
38     return ret;
39 }
40 int main(){
41     six.l=0.0,six.r=60.0;
42     while(scanf("%lf",&D)==1&&D!=-1.0){
43         double ans=0;
44         for(int i=0;i<12;i++){  //枚举时
45             for(int j=0;j<60;j++){  //枚举分
46                 ans+=finds(i,j);
47             }
48         }
49         printf("%.3lf\n",ans/(36.0*12.0));
50     }
51 
52     return 0;
53 }

 

posted @ 2018-02-13 18:52  Blogggggg  阅读(164)  评论(0编辑  收藏  举报