原题来源:杭电1006
Problem Description
The three hands of the clock are rotating every second and meeting each other many times everyday. Finally, they get bored of this and each of them would like to stay away from the other two. A hand is happy if it is at least D degrees from any of the rest. You are to calculate how much time in a day that all the hands are happy.
Input
The input contains many test cases. Each of them has a single line with a real number D between 0 and 120, inclusively. The input is terminated with a D of -1.
Output
For each D, print in a single line the percentage of time in a day that all of the hands are happy, accurate up to 3 decimal places.
Sample Input
Sample Output
该题目要计算一天中时针、分针、秒针之间角度大于某一角度的概率。最朴素的算法是模拟每秒(每0.1秒或0.01秒)时计算三个针子之间角度,但计算量超大。以下java程序便是一例,由于计算量过大,会超时,但如减小计算量,精度又无法满足需求:
import java.io.*;
import java.util.*;
public class P1006_2 {
public static void main(String args[]) throws IOException{
Scanner sin = new Scanner(System.in);
int count ;
double data[] = new double[3];
float distance ;
distance = sin.nextFloat();
while((int)distance != -1){
count = 0;
if(distance >=120)
System.out.println("0.000");
else
{
//12小时分时秒针重合一次,每小时时分秒针分别走30,360,360*60度
for(int i = 0;i<12;i++)
//每小时均分30份,每份时时分秒针分别走1,12,720度
for(int j=0;j<30;j++)
// 每份再均分1000小份
for(int k=0;k<1000;k++){
data[0] = (i * 30 + j + 0.001 * k);
data[1] = (j * 12 + 0.012 * k);
data[2] = (k* 0.72)%360;
Arrays.sort(data);
if(data[1]-data[0]>=distance&data[2]-data[1]>=distance&360+data[0]-data[2]>=distance)
count ++;
}
double percent = (double)count /360/10;
System.out.printf("%f\n",percent);
}
distance = sin.nextFloat();
}
}
}
不能AC,这是个大问题。后来从网上得到一个巧妙的算法,其原理是以空间换时间。其源程序(c++)如下:
#include <cstdio> #include <iostream> using namespace std;
inline double max(double a,double b,double c) { a= a > b ? a: b; a= a > c ? a: c; return a; } inline double min(double a,double b,double c) { a= a < b ? a: b; a= a < c ? a: c; return a; } int main() { double hdans; double dsm[1444],dsh[1444],dmh[26]; //dsm存放秒针与分针之间的角度,dsh存放秒针与时针之间的角度 //dmh存放分针与时针之间的角度。 double s,m,h;
s=3600.0000/59; m=43200.0000/719; h=43200.0000/11;
while(cin >> hdans && hdans !=-1) { int i,j; int sp[2],mp[2],hp[2]; double sum=0; double x=0,y=0; dsm[0] = (10*hdans)/59; dsh[0] = (120*hdans)/719; dmh[0] = (120*hdans)/11;
dsm[1] = s-dsm[0]; dsh[1] = m-dsh[0]; dmh[1] = h-dmh[0];
for(i=2,j=3; ;i+=2,j+=2) { dsm[i] = dsm[i-2]+s; dsm[j] = dsm[j-2]+s; if(dsm[i]>43200 && dsm[j]>43200) break; } for(i=2,j=3;;i+=2,j+=2) { dsh[i] = dsh[i-2]+m; dsh[j] = dsh[j-2]+m; if(i==1436) i=1436; if(dsh[i]>43200 && dsh[j]>43200) break; } for(i=2,j=3;;i+=2,j+=2) { dmh[i] = dmh[i-2]+h; dmh[j] = dmh[j-2]+h; if(dmh[i]>43200 && dmh[j]>43200) break; } //以上代码用来根据hdans初始化dsm,dsh,dmh; sp[0]=mp[0]=hp[0]=0; sp[1]=mp[1]=hp[1]=1; //sp,mp,hp分别为dsm,dsh,dmh的上下界指针。 while(y<=43200 && x<=43200) { x=max(dsm[sp[0]],dsh[mp[0]],dmh[hp[0]]); y=min(dsm[sp[1]],dsh[mp[1]],dmh[hp[1]]); if(x<y) sum+=y-x;
if(y==dsm[sp[1]]) {sp[0]+=2;sp[1]+=2;} if(y==dsh[mp[1]]) {mp[0]+=2;mp[1]+=2;} if(y==dmh[hp[1]]) {hp[0]+=2;hp[1]+=2;} } printf("%.3f\n",sum/432); }//while return 0; }
|
其中,s,m,h分别表示秒针与分针,秒针与时针,分针与时针重合一次所需要的时间。
dsm,dsh,dmh数组一分为二,偶下标元素表示秒针与分针,秒针与时针,分针与时针之间角度满足时所对应的开始时间,而奇下标元素则表示不满足时所对应的开始时间。
很是巧妙!足见偶学习的空间还是很大的。o(∩_∩)o...哈哈 加油~
分享到:
相关推荐
本资源是关于ACM图论问题的经典讲解,涵盖了常见的ACM图论问题,包括最短路算法及其应用、生成树问题、图论中的圈和块问题、简单网络流问题等。 最短路算法及其应用 最短路问题是图论中的核心问题之一,它是许多更...
【ACM信息竞赛思维角度】在信息学竞赛中,思维方法是至关重要的,它涉及到如何高效地解决问题和优化求解。ACM(国际大学生程序设计竞赛)中的常见解题思想主要包括试验猜想及归纳、模型化、分类及分治以及类比。 ...
《欧洲ACM问题集》是一本专为 ACM(国际大学生程序设计竞赛)爱好者精心准备的资源集合。这个压缩包包含了PDF格式的文档,涵盖了大量 ACM 比赛中的经典问题,旨在帮助参赛者提升编程技能,熟悉比赛环境,增强算法...
ACM程序设计大赛算法模板 ACM模板 一般编程问题 【实例简介】 这是我整理所得,不代表是我写的、、对于有些参考没有标记的,欢迎你们提出我来修正!感谢那些浙大ACM的前辈!!! ACM程序设计大赛算法模板 ACM模板 ...
这份“ACM常用代码”压缩包很可能是为了帮助参赛者准备比赛而收集的一系列常见问题的解决方案或者模板代码。下面将详细介绍这些常用代码可能涉及的知识点,并给出相关的编程实践建议。 1. **排序算法**:在ACM比赛...
该题目是一个典型的ACM竞赛中的数字统计问题,通过对给定的代码进行分析,我们不仅可以了解如何解决这类问题的具体算法思路,还可以学习到解决类似问题的一些通用技巧,比如位运算的应用、动态规划思想的体现以及...
国际大学生程序设计竞赛(ICPC,International Collegiate Programming Contest)是ACM的一项重要活动,旨在提升学生的算法设计、问题解决以及团队合作能力。参赛者需要在限定时间内解决一系列复杂的问题,这些问题...
ACM 在线测评第二题,括号配对!表示完全是自己写的,没有参考他人思想!有不足之处请指正!
在ACM(国际大学生程序设计竞赛)中,递归算法是一种常见的解决问题的方法,它通过函数自身调用自身来实现问题的解决。递归的核心在于找到基本情况(base case),即可以直接求解的问题,以及每次递归调用时问题规模...
ACM是一项面向全球大学生的编程竞赛,旨在提升学生的算法设计、问题解决和团队合作能力。 【描述】中的“很好很好很好很好很好学生必备学生必备必备必备”表明这些资源对于参加ACM竞赛的学生来说是非常有价值的参考...
### ACM程序设计基础知识点 #### 一、ACM竞赛概览 - **组织机构与活动**: 本课程由东北林业大学陈宇老师负责,通过邮箱Lg_chenyu@yahoo.com.cn进行联系。课程的主要目的是介绍ACM程序设计的基础概念及入门技巧。 - ...
ACM竞赛是全球范围内影响力极大的编程比赛,旨在提升大学生的算法设计、问题解决以及团队合作能力。这个题库包含了历年来各大赛事中的经典题目,对于学习算法和提高编程技巧具有很高的价值。 标签"acm"明确指出这个...
"ACM java_pku 1689 rubbery_ppt" 提到的可能是关于 Java 语言在解决 ACM 比赛问题中的应用,特别是针对北京大学(PKU)的一道编号为1689的题目 "rubbery" 的解题策略或解析,PPT 格式意味着是以演示文稿的形式呈现。...
在ACM(国际大学生程序设计竞赛)中,参赛队伍需要解决一系列复杂的算法问题,快速而正确地编写程序。上海交大的模板通常会涵盖以下几个核心知识点: 1. **基础算法**:包括排序(快速排序、归并排序、堆排序等)、...
ACM面试题解析 从给定的文件中,我们可以总结出四个不同的问题,每个问题都有其独特的解决方案和要点。 试题一:青蛙相遇问题 该问题的核心是判断两只青蛙是否能够相遇,并计算出它们相遇所需要的跳跃次数。为了...
在ACM(国际大学生程序设计竞赛,International Collegiate Programming Contest)中,参赛者们需要解决一系列算法问题,以此提升编程技巧和逻辑思维能力。ACM算法竞赛是大学教育中一个非常重要的组成部分,它能帮助...
ACM PRO ACM PROACM PRO ACM PROACM PRO ACM PRO
再者,对于浙大ACM网站,其题目设计涵盖了许多实际问题,包括数学问题、逻辑推理、图形处理等,这要求参赛者具备多学科知识。解题源码中可能蕴含了这些问题的巧妙解法,这些方法可能源自数学、物理学甚至生物学等多...
ACM竞赛的核心在于解决各种复杂问题,这些问题往往需要高效且优化的算法来解答。以下将从几个关键知识点进行深入解析: 1. **基础算法**:ACM竞赛中,基础算法如排序(快速排序、归并排序、堆排序等)、搜索(二分...