hdoj1006--Tick and Tick
8438 단어 OJ
The three hands of the clock are rotating every second and meeting each other many times everyday. Finally, they get bored of this and each of them would like to stay away from the other two. A hand is happy if it is at least D degrees from any of the rest. You are to calculate how much time in a day that all the hands are happy.
Input
The input contains many test cases. Each of them has a single line with a real number D between 0 and 120, inclusively. The input is terminated with a D of -1.
Output
For each D, print in a single line the percentage of time in a day that all of the hands are happy, accurate up to 3 decimal places.
Sample Input
0
120
구십
-1
Sample Output
100.000
0.000
6.251
/////////////////////////////
알고리즘 분석
초침(S): 1s 360/60= 6도(degree) 분침(M): 1s 360/60*60= 1/10도(degree) 시침(H): 1s 360/60*60*12= 1/120도(degree)
초침과 분침의 상대 속도는 V(M, S) = 6-1/10 = 59/10 d/s이다.같은 이치로 시침과 초침 V(H, S) = 6-1/120 = 719/120 d/s;V(H,M) = 1/10-1/120 = 11/120 d/s.
초침과 분침의 만남 주기는 T(M, S) = 360/V(M, S) = 3600/59;동일, T(H, S) = 360/V(H, S) = 43200/719;T(H,M)= 360/V(H,M)=43200/11;
하루 24시간 내, 후 12시간은 전 12시간과 상황이 완전히 같기 때문에 12시간만 찾으면 된다.총 12시간 T=12h*60m*60s=43200s
초침과 분침의 만남 횟수는 N(M, S) = T/T(M, S) = 59*12 = 708 동리, N(H, S) = T/T(H, S) = 719 N(H, M) = T/T(H, M) = 11
주기적인 법칙으로 알 수 있듯이 초침과 분침 사이의 각도를 함수 F(t)로 표시하면 F(t)는 어느 순간 t와 두 침 사이의 각도이다.F(t+n*T(M, S)=F(t), 그중 n은 자연수, 동리, F(t+n*T(H, S)=F(t)F(t+n*T(H, M)=F(t)
그래서 우리는 첫 번째 주기 내의 각 지침 간의 행복 시간 구간을 계산하고 몇 개의 각자 주기를 더하면 여전히 행복 구간이다.각도 차가 적어도 D일 때 초침과 분침이 행복하다고 가정하면 첫 번째 주기 T(M, S)에서 D<= V(M, S)*t<= 360-D
t1=D/V(M, S)t2=(360-D)/V(M, S);주기적으로 happy(tms)=(t1+n*T(M, S), t2+n*T(M, S)) 0 <= n
L = happy(t ms) X happy(t hs) X happy(t hm), (X는 관계를 나타낸다) 하면 된다.
#include <iostream>
#include <iomanip>
using namespace std;
const int T = 360*120, NMS = 708,NHM = 11, NHS = 719; //
const double F = 0.0466631; //F ,
const double hmlen = T*F/NHM,mslen = T*F/NMS,hslen = T*F/NHS;
struct interval
{
double low,high;
};
interval andset(interval S1,interval S2)
{
interval zone;
zone.low = S1.low > S2.low ? S1.low : S2.low;
zone.high = S1.high < S2.high ? S1.high : S2.high;
if( zone.low >= zone.high )
zone.low = zone.high = 0.0;
return zone;
}
int main()
{
int D=0;
while(cin>>D&&D!=-1)
{
double len = 0.0;
interval ms,hs,hm;
hm.low = hmlen*D/360 - hmlen;
hm.high = - hm.low -hmlen;
ms.low = mslen*D/360 - mslen;
ms.high = - ms.low -mslen;
hs.low = hslen*D/360 - hslen;
hs.high = - hs.low -hslen;
for(int i=0,j=0,k=0;i<NHM;i++)
{
hm.low+=hmlen;
hm.high+=hmlen;
for(;j<NMS;j++)
{
ms.low+=mslen;
ms.high+=mslen;
interval temp1 = andset(hm,ms);
if(temp1.low!=0||temp1.high!=0)
{
for(;k<NHS;k++)
{
hs.low+=hslen;
hs.high+=hslen;
interval temp2 = andset(temp1,hs);
len+=temp2.high-temp2.low;
if(hs.high>=temp1.high)
{
hs.low-=hslen;
hs.high-=hslen;
break;
}
}
}
if(ms.high>=hm.high)
{
ms.low-=mslen;
ms.high-=mslen;
break;
}
}
}
cout<<setprecision(3)<<fixed<<len/(432*F)<<endl;
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
9도 OJ 1116: 가감승제(기초문제)시간 제한: 1초 메모리 제한: 32메가바이트 특수 판제: 아니요 제출: 1466 해결 방법: 902 제목 설명: 입력한 연산자에 따라 입력한 정수에 대해 간단한 정수 연산을 진행한다.연산자는 더하기 +, 빼기 -,...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.