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 }
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”