时针分针角度问题1094.Clock

本文介绍了一道算法题目,需要计算五个不同时间点的时钟角度并找出中位数时间。通过解析输入的时间序列,计算每个小时和分钟对应的角度,并进行排序来找到中位数时间。

1094.Clock

Time Limit: 1000 MS    Memory Limit: 32768 KB
Total Submission(s): 90    Accepted Submission(s): 35

Description

There is an analog clock with two hands: an hour hand and a minute hand. The two hands form an angle. The angle is measured as the smallest angle between the two hands. The angle between the two hands has a measure that is greater than or equal to 0 and less than or equal to 180 degrees.
Given a sequence of five distinct times written in the format hh : mm , where hh are two digits representing full hours (00 <= hh <= 23) and mm are two digits representing minutes (00 <= mm <= 59) , you are to write a program that finds the median, that is, the third element of the sorted sequence of times in a nondecreasing order of their associated angles. Ties are broken in such a way that an earlier time precedes a later time.
For example, suppose you are given a sequence (06:05, 07:10, 03:00, 21:00, 12:55) of times. Because the sorted sequence is (12:55, 03:00, 21:00, 06:05, 07:10), you are to report 21:00.

Input

The input consists of T test cases. The number of test cases (T) is given on the first line of the input file. Each test case is given on a single line, which contains a sequence of five distinct times, where times are given in the format hh : mm and are separated by a single space.

Output

Print exactly one line for each test case. The line is to contain the median in the format hh : mm of the times given. The following shows sample input and output for three test cases.

Sample Input

3
00:00 01:00 02:00 03:00 04:00
06:05 07:10 03:00 21:00 12:55
11:05 12:05 13:05 14:05 15:05

Sample Output

02:00
21:00
14:05

Source



#include<iostream>

#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath> 
using namespace std;
struct mytime
{
int shi;
int fen;
double du;
int time;
}t[5];
bool cmp(mytime bb,mytime cc)
{
if(bb.du != cc.du) return bb.du < cc.du;
return bb.time < cc.time;
// if(b.du < c.du) return true;
// else if(b.du > c.du) return false;
// else
// {
// if(b.shi < c.shi) return true;
// else if(b.shi > c.shi) return false;
// else
// {
// if(b.fen < c.fen) return true;
// else if(b.fen > c.fen) return false;
// }
//
// }

}
int main()
{

int a,b,i,q;
double cop;
cin>>q;
while(q--)
{
for(i = 0;i < 5;i++)
{
scanf("%d:%d",&a,&b);
t[i].shi = a;
t[i].fen = b;
t[i].time = a * 60 + b;
if(a > 12)
{
a = a - 12;
}
cop = fabs(a * 30 - b * 6 + b * 0.5);
if(cop > 180) cop = 360 - cop;
t[i].du = cop;
}
sort(t,t+5,cmp);
printf("%02d:%02d\n",t[2].shi,t[2].fen);


}





return 0;

 } 


WA了好几遍,现在终于明悟:是我考虑的太少了,分针的指向对时针的指向是有所影响的,一分钟会让时针多偏移0.5度,依次类推,而我没有考虑到时针的具体指向,定义了int存角度,没有算是min*0.5的角度

以后看来还得联系联系实际,不能做死题啊~~

SSD1306是一款针对OLED屏幕的驱动芯片,它支持I2C/SPI等多种通讯方式。在使用STM32通过I2C协议控制SSD1306时,我们可以通过以下步骤来绘制时针分针: 1. 配置STM32的I2C外设,并初始化SSD1306。 2. 在SSD1306上创建一个画布,用于绘制时针分针。 3. 计算当前时间,得到时、分、秒的数值。 4. 计算时针分针角度。 5. 在画布上绘制时针分针。 6. 将画布上的内容刷新到SSD1306屏幕上。 具体实现细节可以参考下面的代码片段: ```c // 初始化SSD1306 void ssd1306_init(void) { // TODO: 配置I2C外设 // 初始化SSD1306 ssd1306_write_command(0xAE); // 关闭显示 ssd1306_write_command(0xD5); // 设置时钟分频因子,震荡器频率 ssd1306_write_command(0x80); // 0x80, 1000000b ssd1306_write_command(0xA8); // 设置驱动路数 ssd1306_write_command(0x3F); // 默认0x3F(1/64),共64行 ssd1306_write_command(0xD3); // 设置显示偏移 ssd1306_write_command(0x00); // 默认为0 ssd1306_write_command(0x40); // 设置显示开始行 [5:0],行数从0开始计数 ssd1306_write_command(0x8D); // 电荷泵设置 ssd1306_write_command(0x14); // bit2,开启/关闭 (0关闭,1开启) ssd1306_write_command(0x20); // 设置内存地址模式 ssd1306_write_command(0x00); // 0x00,水平寻址模式; 0x01,垂直寻址模式; 0x02,页寻址模式(默认) ssd1306_write_command(0xA1); // 设置段重定义,bit0:0,0->0;1,0->127; ssd1306_write_command(0xC8); // 设置COM硬件扫描方式 ssd1306_write_command(0xDA); // 设置COM硬件配置 ssd1306_write_command(0x12); ssd1306_write_command(0x81); // 对比度设置 ssd1306_write_command(0xCF); ssd1306_write_command(0xD9); // 设置预充电周期 ssd1306_write_command(0xF1); ssd1306_write_command(0xDB); // VCOMH 电压倍率设置 ssd1306_write_command(0x40); ssd1306_write_command(0xA4); // 全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) ssd1306_write_command(0xA6); // 设置显示方式;bit0:1,反相显示;0,正常显示 ssd1306_write_command(0xAF); // 开启显示 // 创建画布 memset(g_display_buffer, 0, sizeof(g_display_buffer)); } // 绘制时针分针 void draw_clock_hands(uint8_t hour, uint8_t minute) { float hour_angle = (hour % 12) * 30 + (minute / 2); // 计算时针角度,每小时30度,每分钟半度 float minute_angle = minute * 6; // 计算分针角度,每分钟6度 // 计算时针分针的坐标点 int16_t hour_x = (int16_t)(CLOCK_RADIUS * sin(hour_angle * PI / 180)); int16_t hour_y = (int16_t)(CLOCK_RADIUS * cos(hour_angle * PI / 180)); int16_t minute_x = (int16_t)(CLOCK_RADIUS * sin(minute_angle * PI / 180)); int16_t minute_y = (int16_t)(CLOCK_RADIUS * cos(minute_angle * PI / 180)); // 在画布上绘制时针分针 draw_line(CENTER_X, CENTER_Y, CENTER_X + hour_x, CENTER_Y - hour_y); draw_line(CENTER_X, CENTER_Y, CENTER_X + minute_x, CENTER_Y - minute_y); // 刷新画布到屏幕上 refresh_display(); } // 刷新画布到屏幕上 void refresh_display(void) { uint8_t cmd; for (uint8_t i = 0; i < PAGE_COUNT; i++) { cmd = 0xB0 + i; ssd1306_write_command(cmd); // 设置页地址 cmd = 0x00; ssd1306_write_command(cmd); // 设置低列地址 cmd = 0x10; ssd1306_write_command(cmd); // 设置高列地址 for (uint8_t j = 0; j < COLUMN_COUNT; j++) { ssd1306_write_data(g_display_buffer[i][j]); } } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值