题目:
Clock
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 0 Accepted Submission(s): 0
Problem Description
wls 有一个钟表,当前钟表指向了某一个时间。
又有一些很重要的时刻,wls 想要在钟表上复现这些时间(并不需要依次复现)。我们可以顺时针转动秒针,也可以逆时针转动秒针,分针和时针都会随着秒针按规则转动,wls 想知道秒针至少转动多少角度可以使每个时刻至少都会被访问一次。
注意,时钟上的一种时针分针秒针的组合,可以代表两个不同的时间。
Input
第一行一个整数 n 代表有多少个时刻要访问。
第二行三个整数 h,m,s 分别代表当前时刻的时分秒。
最后n行每一行三个整数 hi,mi,si 代表每个要访问的时刻的时分秒。
1 ≤ n ≤ 86, 400
0 ≤ h, hi < 24
0 ≤ m, mi, s, si < 60
Output
输出一行一个数代表秒钟转的角度,答案保留两位小数。
Sample Input
1
0 1 0
0 1 1
Sample Output
6.00
总共可以分为四种情况:只顺时针转,只逆时针转,先顺时针再逆时针,先逆时针再顺时针。
所以的情况直接暴力模拟就行,对于后面两种情况对每次顺时针和逆时针结束的终点进行枚举然后求出值。注意:每一个时间都是一个对象,包含距离给出的顺时针角度和逆时针角度。
#include<bits/stdc++.h>
#define INF 0x3F3F3F3F
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int n,m;
int t;
int tn(int x)
{
int z=x%12;
return z;
}
struct node
{
int shun;
int ni;
int a,b,c;
int num;
} dian[90000];
int tim(int h,int m,int s)
{
int zz=h*3600+m*60+s;
return zz;
}
bool comp(node a,node b)
{
return a.shun<b.shun;
}
int main()
{
scanf("%d",&n);
int qx,qy,qz;
scanf("%d",&qx);
scanf("%d",&qy);
scanf("%d",&qz);
qx=tn(qx);
int qi=tim(qx,qy,qz);
int cnt=1;
for(int i=1; i<=n; i++)
{
int a,b,c;
scanf("%d",&a);
scanf("%d",&b);
scanf("%d",&c);
a=tn(a);
dian[cnt].a=a;
dian[cnt].b=b;
dian[cnt].c=c;
int zz=tim(a,b,c);
int kk=zz-qi;
if(kk<0)
{
dian[cnt].ni=abs(kk);
dian[cnt].shun=43200-dian[cnt].ni;
cnt++;
}
else
{
if(kk>0)
{
dian[cnt].shun=kk;
dian[cnt].ni=43200-dian[i].shun;
cnt++;
}
if(kk==0)
{
continue;
}
}
}
sort(dian+1,dian+cnt,comp);
int mi=INF;
int ss=dian[cnt-1].shun; //全顺
mi=min(ss,mi);
ss=dian[1].ni; //全逆
mi=min(ss,mi);
for(int i=1; i<=cnt-1; i++) //枚举先顺后逆的讨论
{
int summ=0;
summ=summ+dian[i].shun*2+dian[i+1].ni;
mi=min(mi,summ);
}
for(int i=cnt; i>=2; i--)
{
int summ=0;
summ+=dian[i].ni*2+dian[i-1].shun;
mi=min(mi,summ);
}
double fin=(double)mi*1.0*6.00;
printf("%.2lf\n",fin);
return 0;
}