【2016杭电女生赛1004】【枚举 数学解方程】Clock 下一时刻时针分针恰成角度

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define tmpmtmps(x,y) memset(x,y,sizeof(x))
#define tmpmC(x,y) memcpy(x,y,sizeof(x))
#define tmpmP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 0, tmpm = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int casenum, casei;
void solve()
{
	int h, m, s;
	int angle;
	while (~scanf("%d:%d:%d%d", &h, &m, &s, &angle))
	{
		angle *= 120;
		int t = 3600 * h + 60 * m + s;
		int DIF = 1e9;
		int ansh, ansm, anss;
		int tmpx, tmpm, tmps;
		for (int tmph = 0; tmph < 12; ++tmph)
		{
			tmpx = tmph * 3600 - angle;
			tmpm = tmpx / 660;
			tmps = tmpx % 660 / 11;
			int T = 3600 * tmph + 60 * tmpm + tmps;
			int dif = T - t;
			if (dif <= 0)dif += 12 * 3600;
			if (dif < DIF)
			{
				DIF = dif;
				ansh = tmph;
				ansm = tmpm;
				anss = tmps;
			}
			tmpx = tmph * 3600 + angle;
			tmpm = tmpx / 660;
			tmps = tmpx % 660 / 11;
			T = 3600 * tmph + 60 * tmpm + tmps;
			dif = T - t;
			if (dif <= 0)dif += 12 * 3600;
			if (dif < DIF)
			{
				DIF = dif;
				ansh = tmph;
				ansm = tmpm;
				anss = tmps;
			}
		}
		printf("Case #%d: %02d:%02d:%02d\n", ++casei, ansh, ansm, anss);
	}
}
int main()
{
	solve();
	return 0;
}
/*
【trick&&吐槽】
这里注意,
因为是求下一个时刻,
所以不光在dif<0时要转化为正数
在dif=0时,也要转化为正数(不然时刻相同)

【题意】
时间为12小时制。
告诉你一个时刻,让你输出在这个时刻之后的下一个时刻,
满足:该时刻,时针分针掐好相差某个的角度为angle。
(注意,满足要求的时刻不一定是恰好以秒为单位,可以是秒与秒之间的时刻,我们可以向下取整)

【类型】
暴力枚举 解方程

【分析】
如何使得时针与分针的角度恰好相差某个角度呢?我们考虑解方程就好啦!
钟表有360个度,

一,考虑时针位置
每小时为30度
每分钟为1/2度
每秒钟为1/120度
于是我们不妨使得所有与角度相关的单位都*=120,转化成整数,告别精度误差。
(其实也就可以看做是为:以秒为基本单位。)
转变为:
每小时为3600
每分钟为60
每秒钟为1(其实不用考虑这个)

二,考虑分针位置
每分钟为6度
每秒钟为0.1度
我们一样*=120,转变为——
每分钟为720
每秒钟为12(其实不用考虑这个)

然后,同时定义00:00:00时刻的角度为0,11:59:59时刻的角度为43299
这样,我们可以枚举此时的小时h(0 <= h < 12),
不过,时针和分针的位置,其实还都受此时的分与秒的影响与限制。
然而,因为按照题目所说,我们求得的可能并不一定恰好是以秒为单位。
于是,我们不妨把余下来的时刻设为x分(x为浮点数)

显然:时针的角度tmphpos = h * 3600 + x * 60;
同时:分针的角度tmpmpos = x * 720.

进而得到——
angle=abs(h*3600 - x*660)/120
取下绝对值,得到——
	120*angle = h*3600 - x*660 
or	120*anlge = x*660 - h*3600

即:
   x=(3600*h-120*anlge)/660
or x=(120*angle+3600*h)/660

于是,这里h已知(暴力枚举),angle已知。
便可以求得x。
因为x是double类型。
所以,/660之后,直接向下取整,便是分钟。
%660之后,再均分为60份,并向下取整(即%660之后再/=11),便是秒钟。

【时间复杂度&&优化】
O(12T)

*/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值