【例1】时针分针与秒针
问题描述
给定一个24小时格式的数字时间,问给定的这个时刻时针与分针、时针与秒针、分针与秒针 之间的夹角分别是多少?
输入
有T(1≤T≤104)组测试用例。
对于每组测试用例,用一行hh:mm:ss描述给定的时间。0≤hh<24,0≤mm<60,0≤ss<60。
输出
对于每组测试用例,输出像A/B这样的实数。(A和B是互质的)。如果它是一个整数,那么就直接输出它。描述时针和分针、时针和秒针、分针和秒针之间的角度。
输入样例
4
00:00:00
06:00:00
12:54:55
04:40:00
输出样例
0 0 0
180 180 0
1391/24 1379/24 1/2
100 140 120
(1)编程思路。
将表盘的0点(或12点)作为起点,整个表盘转一圈360度,用60个刻度线分成60格,每1格就是6度。
时钟每走1个小时,时针走5格,转30度;分针走60格,转360度(正好走一圈,相当转0度);秒针走3600格,转21600度(走了60圈,也相当转0度)。
时钟每走1分钟,分针走1格,转6度;时针走5/60格,转1/2度;秒针走60格,相当转了0度。
时钟每走1秒,秒针走1格,转6度;分针走1/60格,转1/10度;时针走5/3600格,相当转了1/120度。
因此,对于任意一个时刻hh:mm:ss,有
时针转的度数为 30*hh + 1/2*mm + 1/120*ss
分针转的度数为 6*mm + 1/10*ss
秒针转的度数为 6*ss
计算出各指针转的度数后,它们之间的差值就是它们的夹角。
由于计算时有分数比1/120,将它们都乘以120(相当于通分,分母为120),这样只看各分子部分。有
时针转的度数为 3600*hh + 60*mm + ss
分针转的度数为 720*mm + 12*ss
秒针转的度数为 720*ss
(2)源程序。
#include <stdio.h>
int gcd(int a,int b)
{
if (a%b==0) return b;
else return gcd(b,a%b) ;
}
void output(int a,int b) // 计算圆盘上转过a度和b度的两指针之间的夹角并输出
{
int x;
x=a>b? a-b:b-a ;
if (x % 120 == 0)
{
x /= 120 ;
x %= 360 ;
if (x%360 == 0 )
printf("0 ") ;
else if (x%180 == 0 )
printf("180 ") ;
else
printf("%d ", x<180?x:360-x) ;
}
else
{
x=x%43200;
if (x>43200-x) // 通分后,圆盘一周360度变成 43200度(360*120)
x=43200-x;
int k = gcd(x,120) ;
printf("%d/%d ", x/k, 120/k) ;
}
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
int h,m,s,x,y,z;
scanf("%d:%d:%d", &h, &m, &s) ;
x = 3600*h + 60*m + s ;
y = 720*m + 12*s ;
z = 720*s ;
output(x,y);
output(x,z);
output(y,z);
printf("\n") ;
}
return 0;
}
将上面的源程序提交给HDU 题库 HDU 5387 Clock (http://acm.hdu.edu.cn/showproblem.php?pid=5387),可以Accepted。
将上面的源程序略作修改,还可以提交给 HDU 2076 夹角有多大 (http://acm.hdu.edu.cn/showproblem.php?pid=2076)。
【例2】时针与分针的夹角
问题描述
给定一个时间HH:MM:SS和一个参数a,请你计算满足以下条件的下一个时间:
1.时针和分针形成的角度是a。
2.时间可以不是整数,但向下舍入。例如12:34:56.78向下舍入为12:34:56。
输入
输入包含多个测试用例。
每个测试用例包含两行。
第一行是时间HH:MM:SS(0≤HH<12,0≤MM<60,0≤SS<60)。
第二行包含一个整数a(0≤a≤180).
输出
对于每个测试用例,输出一行包含测试用例编号和答案HH:MM:SS。
输入样例
0:59:59
30
01:00:00
30
输出样例
Case #1: 01:00:00
Case #2: 01:10:54
(1)编程思路。
对给定的时间,一秒一秒的加1(向前走一秒到下一个时间)进行枚举,每次枚举一个时间,计算时针与分针的夹角r,若r正好等于a,输出当前时间并结束枚举。若r不是正好等于a,则输出找到的第1个形成夹角大于a的前一秒。为此,程序中用pr保存前1秒时间(ph:pm:ps)指针与分针的夹角,这样当前一秒的夹角pr小于a,但后一秒的夹角大于a,即pr!=a && (pr-a)*(r-a)<0时,输出前1秒时间ph:pm:ps即可。
(2)源程序。
#include <stdio.h>
int main()
{
int iCase=0;
int h,m,s;
while (scanf("%d:%d:%d",&h,&m,&s)!=EOF)
{
int a;
scanf("%d", &a) ;
int ph=h,pm=m,ps=s;
double r,pr;
pr=(3600*h + 60*m + s-720*m - 12*s+43200)%43200/120.0;
if (pr > 180) pr=360-pr;
while (1)
{
s++;
if (s>=60)
{
s=s%60;
m++;
if (m>=60)
{
m=0; h=(h+1)%12;
}
}
r=(3600*h + 60*m + s-720*m - 12*s+43200)%43200/120.0;
if (r > 180) r=360-r;
if (r==a)
{
printf("Case #%d: %02d:%02d:%02d\n",++iCase,h,m,s);
break;
}
else if (pr!= a && (r-a) * (pr-a) < 0)
{
printf("Case #%d: %02d:%02d:%02d\n",++iCase,ph,pm,ps);
break;
}
pr=r;
ph=h;
pm=m;
ps=s;
}
}
return 0;
}
将上面的源程序提交给HDU 题库 HDU 5705 Clock (http://acm.hdu.edu.cn/showproblem.php?pid=5705),可以Accepted。
【例3】时间复现
问题描述
小明有一个钟表,当前钟表指向了某一个时间。
又有一些很重要的时刻,小明想要在钟表上复现这些时间(并不需要依次复现)。我们可以顺时针转动秒针,也可以逆时针转动秒针,分针和时针都会随着秒针按规则转动,小明想知道秒针至少转动多少角度可以使每个时刻至少都会被访问一次。
注意,时钟上的一种时针分针秒针的组合,可以代表两个不同的时间。
输入
第一行一个整数 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
(1)编程思路。
我们知道,每小时有3600秒,每分钟有60秒,每秒秒针转6度。因此,对于任意一个时刻hh:mm:ss来说,秒针一共会顺时针转(hh * 3600 + mm * 60 + ss)*6 度。
先求出需要每个复现的时间相对当前时间需要顺时针转过的度数,并保存到数组rotate中。在将数组按照转过的度数从小到大排序,即最小转过的角度保存在rotate[1]中,最大转过的角度保存在rotate[N]中。排序后,要复现N个时刻。可以在以下四种情况中取最小值即可。
① 秒针只顺时针走。走到需要转过的最大角度rotate[N]即可。
② 秒针只逆时针走。走到需要转过的最小角度rotate[1]即可,由于是逆时针旋转,实际转过的角度等于aRound-rotate[1]。aRound为时钟上时针转完整一圈,秒针需要转的度数360*60*12。
③ 先顺时针走到某个角度rotate[i],再逆时针走到其下一个角度rotate[i+1]。此时,秒针实际转过的度数为 rotate[i] * 2 + (aRound - rotate[i + 1])。
④ 逆时针走到某个角度rotate[i],再顺时针走到其前一个角度rotate[i-1]。此时,秒针实际转过的度数为 rotate[i-1] + (aRound - rotate[i])*2。
(2)源程序。
#include <stdio.h>
#include <algorithm>
using namespace std;
#define aRound 360 * 60 * 12 // 时针转一整圈(12小时),秒针转过的度数
int main()
{
int n;
while (scanf("%d", &n)!=EOF)
{
int h,m,s,nowrot,tt;
scanf("%d%d%d", &h, &m, &s);
if (h >= 12) h -= 12;
nowrot = (h * 3600 + m * 60 + s)*6; // 当前时刻秒针转过的度数
int i,rotate[86405]; // 保存各时刻从当前时刻起 秒针顺时针转过的度数
for (i = 1; i <= n; i++)
{
scanf("%d%d%d", &h, &m, &s);
if (h >= 12) h -= 12;
tt = (h * 3600 + m * 60 + s)*6;
rotate[i] = tt - nowrot;
if (rotate[i] < 0)
rotate[i] += aRound;
}
sort(rotate + 1, rotate + n + 1); // 将各时刻秒针转过的度数从小到大排序
int ans = aRound + 1000000;
rotate[0] = aRound;
rotate[n + 1] = aRound;
if (ans>rotate[n]) ans=rotate[n]; // 秒针一直顺时针转过最大度数
if (ans>aRound-rotate[1]) ans=aRound-rotate[1]; // 秒针一直逆时针转过最小度数
for (i = 1; i <= n; i++) // 先顺时针转到某个度数,再逆时针转到其下一个度数
{
tt=rotate[i] * 2 + (aRound - rotate[i + 1]);
if (ans>tt) ans=tt;
}
for (i = 1; i <= n; i++) // 先逆时针转到某个度数,再顺时针转到其下一个度数
{
tt=rotate[i-1] + (aRound - rotate[i])*2;
if (ans>tt) ans=tt;
}
printf("%d.00\n", ans);
}
return 0;
}
将上面的源程序提交给HDU 题库 HDU 6551 Clock (http://acm.hdu.edu.cn/showproblem.php?pid=6551),可以Accepted。
【例4】时钟
问题描述
从a点b分到s点t分时针和分针重合多少次?
输入
有多组数据,每组1行4个数 a,b,s,t. 1<=a,s <=12, 0<=b,t<60。0 0 0 0结束。
输出
每组测试用例,用1行输出一个整数,表示分针与时针的相遇次数。
输入样例
12 50 1 2
3 8 3 20
2 45 11 0
11 0 3 20
1 2 12 50
3 20 3 8
0 0 0 0
输出样例
0
1
8
4
11
10
(1)编程思路。
本题主要看分针(相对时针)在这个时间段内可以循环多少圈,每循环一圈就是相遇一次。
设初始时为00:00,此时分针与时针重合在一起。之后时针在走,分针也在走。每次分针比时针多走一圈,它们就会相遇一次(重合在一起一次)。
对于任意一个时间hh:mm,我们需要计算分针相比时针多走几圈。
我们知道,12个小时,时针正好走1圈,而分针走了12圈(每1小时走1圈),相比时针,分针多走了12-1=11圈。也就是说在12小时(也是720分钟)内,时针与分针会重合11次。即1分钟会多走 11/720圈。
对于时间hh:mm,分针比时针多走的圈数为 (hh*60+mm)*11/720。
两个时间的圈数差,就是这个时间段内分针与时针的相遇次数。
(2)源程序。
#include <stdio.h>
int main()
{
int a,b,s,t,ans;
while (scanf("%d%d%d%d",&a,&b,&s,&t) && (a || b || s || t))
{
a=a%12;
s=s%12;
int s1=(a*60+b)*11;
int s2=(s*60+t)*11;
if (s2<s1) s2+=720*11;
ans=s2/720-s1/720; // 两个时间的圈数差就是它们的相遇次数
if (s1==0) ans++; // 出发时相遇加1
printf("%d\n",ans);
}
return 0;
}
将上面的源程序提交给HDU 题库 HDU 2180 时钟 (http://acm.hdu.edu.cn/showproblem.php?pid=2180),可以Accepted。
在理解了时钟上时针、分针和秒针转动规律的基础上,可以将HDU题库中如下的几道题目作为练习。
【练习1】HDU Clock (http://acm.hdu.edu.cn/showproblem.php?pid=1209)。
// 按照时针与分针的夹角大小来排序
#include <stdio.h>
typedef struct
{
int h,m;
double r; // 时针与分针的夹角
}Node;
int cmp(Node x,Node y)
{
if (x.r!=y.r) return x.r>y.r;
if (x.h!=y.h) return x.h>y.h;
return x.m>y.m;
}
double fabs(double x)
{
return x>0?x:-x;
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
Node a[5],temp;
int i,j;
for (i = 0;i<5;i++)
{
scanf("%d:%d",&a[i].h,&a[i].m);
if (a[i].h>12)
a[i].r = fabs(30.0*(a[i].h-12)+a[i].m/2.0-6.0*a[i].m);
else
a[i].r = fabs(30.0*a[i].h+a[i].m/2.0-6.0*a[i].m);
if (a[i].r>180)
a[i].r = 360-a[i].r;
}
for (i=0;i<5-1;i++)
for (j=0;j<5-1-i;j++)
if (cmp(a[j],a[j+1]))
{
temp=a[j]; a[j]=a[j+1]; a[j+1]=temp;
}
printf("%02d:%02d\n",a[2].h,a[2].m);
}
return 0;
}
参考程序【练习2】HDU 1371 Clock (http://acm.hdu.edu.cn/showproblem.php?pid=1371)。
#include <stdio.h>
int main()
{
printf("Program 3 by team X\n");
printf("Initial time Final time Passes\n");
int a,b,s,t,ans;
while (scanf("%d%d%d%d",&a,&b,&s,&t)!=EOF)
{
printf(" %02d:%02d %02d:%02d",a,b,s,t);
a=a%12;
s=s%12;
int s1=(a*60+b)*11;
int s2=(s*60+t)*11;
if (s2<s1) s2+=720*11;
ans=s2/720-s1/720; // 两个时间的圈数差就是它们的相遇次数
if (s1==0) ans++; // 出发时相遇加1
printf("%8d\n",ans);
}
printf("End of program 3 by team X\n");
return 0;
}
参考程序【练习3】HDU 1393 Weird Clock (http://acm.hdu.edu.cn/showproblem.php?pid=1393)。
#include <stdio.h>
int main()
{
int s,d;
while (scanf("%d%d",&s,&d) && (s||d))
{
if (s >= 60)
s %= 60;
int count = 0,flag = 1;
while (s)
{
s += s*d;
s %= 60;
if(count > 1000)
{
flag = 0;
break;
}
count++;
}
if (flag)
printf("%d\n",count);
else
printf("Impossible\n");
}
return 0;
}
参考程序【练习4】HDU 2395 Alarm Clock (http://acm.hdu.edu.cn/showproblem.php?pid=2395)。
#include <stdio.h>
#include <string.h>
int calc(int a,int b,int mod)
{
int ans1,ans2;
ans1=(a-b+mod)%mod;
ans2=(b-a+mod)%mod;
return ans1<ans2?ans1:ans2;
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
char s1[8],s2[8];
scanf("%s %s",s1,s2);
int h1,m11,m12,h2,m21,m22;
char c1,c2;
if (s1[1]==':')
{
h1=s1[0]-'0';
m11=s1[2]-'0'; m12=s1[3]-'0';
c1=s1[4];
}
else
{
h1=(s1[0]-'0')*10+(s1[1]-'0');
m11=(s1[3]-'0'); m12=s1[4]-'0';
c1=s1[5];
}
if (s2[1]==':')
{
h2=s2[0]-'0';
m21=(s2[2]-'0'); m22=s2[3]-'0';
c2=s2[4];
}
else
{
h2=(s2[0]-'0')*10+(s2[1]-'0');
m21=(s2[3]-'0'); m22=s2[4]-'0';
c2=s2[5];
}
int cnt=0;
if (c1!=c2)
cnt++;
cnt+=calc(h1,h2,12);
cnt+=calc(m11,m21,6);
cnt+=calc(m12,m22,10);
printf("Going from %s to %s requires %d %s\n",s1,s2,cnt,(cnt==1)?"push.":"pushes.");
}
return 0;
}
参考程序
【练习5】HDU 3248 Strange Clock (http://acm.hdu.edu.cn/showproblem.php?pid=3248)。
#include <stdio.h>
int main()
{
int n,m;
while (scanf("%d",&n) && n!=-1)
{
n = (n+270)%360;
m = n / 30;
m=12-m;
if (n%30==0) printf("Exactly %d o'clock\n",m%12);
else printf("Between %d o'clock and %d o'clock\n",(12+m-1)%12,m%12);
}
return 0;
}
参考程序
我想为用户提供旋转网页内容的选项,包括图像、文本和div。这可能吗?附言:我想旋转整个网页。不仅仅是容器div。 最佳答案 你可以使用CSS3-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);http://jsfiddle.net/KdNNy/1/但并非在所有浏览器上都有效。此示例仅适用于firefox和chrome/safari。Opera应该也有。甚至IE编辑以防万一有人认为“哦,他只是在旋转一个DIV!”,检查一下http://jsbin.com/utup
编辑:我更新了program有了答案,效果很好!我正在制作program(请随意尝试)让用户绘制多边形,然后对其进行三Angular剖分。他们可以单击以添加顶点并按Enter键进行三Angular剖分。无论如何,只要我告诉它这些点是以顺时针还是逆时针方式绘制的,该算法就可以正常工作(现在我将其设置为仅适用于顺时针多边形)。几天来我一直在努力解决这个问题,但不知道如何确定这些点是顺时针还是逆时针。尝试使用前面提到的程序绘制形状以获得更好的想法,你可以更好地体验我在说什么,而不是我试图解释它。点的定义如下:functionPoint(x,y){this.x=x;this.y=y;}varv
我正在解决一个更大的问题,我需要一步逆时针旋转二维数组。所以如果我有这个矩阵:1234123434563456旋转之后会是:4466335522441133我找到了solution顺时针旋转:0){$b[count($a[0])-1][]=array_shift($a[0]);if(count($a[0])==0){array_shift($a);}}?>问题是,即使a是一维的或只有一个元素,这也必须有效。因此,1234将变为:4321 最佳答案 $b=call_user_func_array('array_map',array(-
我想使用SAXParser或XMLReader解析xml文件并验证该文件是否符合特定的xsd文件(newFile("example.xsd")).很简单使用Validator在额外的步骤中对xsd文件进行验证,如thisSOanswer.通过将xsd的名称指定为"http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation"来在解析时进行验证,例如thisSOanswer.但是我如何根据newFile("example.xsd")在解析时进行验证? 最佳答案
我有9个屏幕坐标,每个坐标代表9个位置之一。从右上角开始,我希望该位置从第1个位置开始,接下来的顺时针坐标表示第2、3、4等,直到第9个位置,这将是左上角的坐标。这里有人能想出某种数学方法来确定9个坐标中的哪个坐标位于哪个位置吗?它们都是相互关联的,并且永远是相互关联的。示例坐标可以是:(x,y)XY663382543454303454183382418459543209303209653259183259绘制成类似这样的图像:有人有什么想法吗?我只是想要某种形式的编程方式按顺时针顺序列出这些坐标... 最佳答案 找到“圆”的中心,
我想按顺时针顺序对点vector进行排序以形成多边形,但我需要适当的中心才能这样做。我试过平均法,但有几个点根本没有正确排序。以顺时针方式对点进行排序时,找到中心的正确方法是什么?它在凹陷部分失败谢谢这是一张图片:绿色圆圈是中心。它应该看起来更像这样: 最佳答案 如果您没有预定义的中心点,则“按顺时针顺序排序”的概念没有明确定义。如果你只有一堆需要排序的点,而你事先不知道中心点,那么这个问题通常没有单一的解决方案。该问题有许多替代解决方案,每个解决方案都会为您提供不同的多边形作为结果。此外,找到一个允许您通过CW(或CCW)排序重新
我刚刚将启动图像添加到我编写的应用程序中。根据多个来源,该图像应为1024x748(状态栏负20像素)。所以我创建了这样一个图像,将其命名为Default-Landscape~ipad.png并在-Info.plist中设置这些值:LSRequiresIPhoneOSUISupportedInterfaceOrientations~ipadUIInterfaceOrientationLandscapeRightUIInterfaceOrientationLandscapeLeftUILaunchImageFile~ipadDefault-Landscape~ipad.pngUIInte
我正在开发一个iPad应用程序,我试图在其中显示秒针显示秒针运动,就像每秒更新一次一样。-(void)updateClock:(NSTimer*)theTimer{dateComponents=[[NSCalendarcurrentCalendar]components:(NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit)fromDate:[NSDatedate]];seconds=[dateComponentssecond];minutes=[dateComponentsminute];hours=[dateCo
我一直在为此自责,因为我认为这是一个简单的问题,但不知何故我就是找不到解决方案。我正在根据触摸移动事件围绕其anchor旋转CCSprite。这是我用来旋转Sprite的代码。CGPointpreviousLocation=[touchpreviousLocationInView:[touchview]];CGPointnewLocation=[touchlocationInView:[touchview]];//preformallthesamebasicrigonboththecurrenttouchandprevioustouchCGPointpreviousGlLocation
我是android编程的新手。有没有办法让这个带秒针的模拟时钟代替quartz进行扫频(计时码表)运动?有任何示例要下载吗?我将此代码用于时钟:publicclassSecondHandextendsActivity{//privateHandlermHandler=newHandler();protectedstaticfinalStringTAG=SecondHand.class.getName();privateImageViewimg;HandlermHandler;protectedvoidonCreate(BundlesavedInstanceState){super.on