1780 - 2019年我能变强组队训练赛第十八场
题目描述
wls有一个钟表,当前钟表指向了某一个时间。
又有一些很重要的时刻,wls想要在钟表上复现这些时间(并不需要依次复现)。我们可以顺时针转动秒针,也可以逆时针转动秒针,分针和时针都会随着秒针按规则转动,wls想知道秒针至少转动多少角度可以使每个时刻至少都会被访问一次。
注意,时钟上的一种时针分针秒针的组合,可以代表两个不同的时间。
输入
第一行一个整数n代表有多少个时刻要访问。
第二行三个整数h,m,s分别代表当前时刻的时分秒。
最后n行每一行三个整数hi,mi,si代表每个要访问的时刻的时分秒。
1≤n≤86,400
0≤h,hi<24
0≤m,mi,s,si<60
输出
输出一行一个数代表秒钟转的角度,答案保留两位小数。
样例输入
复制样例数据
1
0 1 0
0 1 1
样例输出
6.00
Contest1780 - 2019年我能变强组队训练赛第十八场 clock
题解:把时间排序去重后进行顺时针及逆时针的暴力;
例如顺时针暴力是:枚举每一个点,让开始时间先顺时针到这个点,再逆时针从这个点到这个点的下一个点;
逆时针暴力和顺时针差不多,只是把方向都换一下就好,就是先让开始时间先逆时针到一个点,再顺时针从这个点到下一个
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
int Min=1000000007;
struct node
{
int hi,mi,si,miao;//miao是把时间转换为秒来计算
} Time[100005],start;
bool cmp(node a,node b)
{
return a.miao<b.miao;
}
int atob(node a,node b,int f)//时间a到时间b,f=0代表逆时针,f=1代表顺时针
{
if(f==0)
{
if(b.miao>a.miao)
{
return (43200-b.miao+a.miao)*6;
}
return (a.miao-b.miao)*6;
}
if(b.miao<a.miao)
return (43200-a.miao+b.miao)*6;
return (b.miao-a.miao)*6;;
}
int main()
{
int n;
scanf("%d",&n);
scanf("%d %d %d",&start.hi,&start.mi,&start.si);
if(start.hi>=12)start.hi=start.hi-12;
start.miao=start.hi*3600+start.mi*60+start.si;
for(int i=1; i<=n; ++i)
{
scanf("%d %d %d",&Time[i].hi,&Time[i].mi,&Time[i].si);
if(Time[i].hi>=12)Time[i].hi=Time[i].hi-12;
Time[i].miao=Time[i].hi*3600+Time[i].mi*60+Time[i].si;
}
sort(Time+1,Time+n+1,cmp);//按miao进行排序
int z=1,len=1;
for(; z<=n; ++z)//找到第一个与开始时间不一样的,就是排序去重的第一步
if(Time[z].miao!=start.miao)
{
Time[1]=Time[z];
break;
}
for(int i=z+1; i<=n; ++i)//排序去重
if(Time[i].miao!=Time[len].miao&&Time[i].miao!=start.miao)Time[++len]=Time[i];
int poi=0;
for(int i=1; i<=len; ++i)//找到第一个大于start的时间
if(Time[i].miao>start.miao)
{
poi=i;
break;
}
if(poi==0)//如果所有时间都小于开始时间
{
Min=min(Min,atob(start,Time[1],0));
for(int i=1; i<len; ++i)
{
Min=min(Min,atob(start,Time[i],1)+atob(Time[i],Time[i+1],0));
}
Min=min(Min,atob(start,Time[len],1));
for(int i=len;i>1;--i){
Min=min(Min,atob(start,Time[i],0)+atob(Time[i],Time[i-1],1));
}
printf("%d.00\n",Min);
return 0;
}
for(int i=poi-1; i<=len; ++i)
{
if(i==poi-1)
{
int temp=atob(start,Time[poi],0);
Min=min(Min,temp);
}
else if(i==len&&poi==1)
{
int temp=atob(start,Time[len],1);
Min=min(Min,temp);
}
else
{
int temp=atob(start,Time[i],1),x=i+1;
if(i==len)x=1;
temp+=atob(Time[i],Time[x],0);
Min=min(Min,temp);
}
}
for(int i=1; i<poi; ++i)
{
if(i==poi-1)
{
int temp=atob(start,Time[poi-1],1);
Min=min(Min,temp);
}
else
{
int temp=atob(start,Time[i],1);
temp+=atob(Time[i],Time[i+1],0);
Min=min(Min,temp);
}
}
for(int i=poi-1;i>=1;--i){
if(i-1==0)
Min=min(Min,atob(start,Time[i],0)+atob(Time[i],Time[len],1));
else Min=min(Min,atob(start,Time[i],0)+atob(Time[i],Time[i-1],1));
}
for(int i=len;i>poi;--i){
Min=min(Min,atob(start,Time[i],0)+atob(Time[i],Time[i-1],1));
}
printf("%d.00\n",Min);
return 0;
}