ACM解题总结——HihoCoder1237 (微软笔试题)
2016-08-23 17:57
417 查看
题目来源:
HihoCoder1237
题目要求:
Given a circle on a two-dimentional plane.Output the integral point
in or on the boundary of the circle which has the largest distance from the center.
题目大意:
题目要求很简单:在二维坐标系中给定一个圆,要求找出在圆的范围内,x,y坐标都为整数的,距离圆心最远的点。如果存在多个点,则输出x坐标最大的点,如果依旧存在多个点,那么输出y坐标最大的点。
解答:
本题其实只要通过枚举就可以得出答案,因此难度不大。给定一个圆的圆心(x0, y0)和半径r,我们可以很容易地得到该圆在坐标系中的x坐标的范围,即:[x0 - r, x0 + r],由于所求点的左边只能是整数,因此,我们对这个区间的左右边界分别向上和向下取整,就是所求点的x坐标的范围,即:[ceil(x0-r), floor(x0+r)]。
确定x的范围后,我们对x从floor(x0+r)到ceil(x0-r)依次由大到小遍历整数值,对于给定的x,我们可以做出一条垂直于x轴的直线,直线和圆相交于两点,记为A,B,此时线段AB为圆的一条弦,如下图:
通过垂径定理,我们可以得到A,B点的坐标:
由于所求点的y坐标也必须为整数,因此,我们对A,B点的y坐标值也分别进行向下和向上取整,这样就得到了点A'和B',它们的坐标分别是:
显然,对于线段AB上的所有点,到圆心的距离一定比A点和B点要小。而对于线段AB上所有x坐标和y坐标均为整数的点,它到圆心的距离一定不可能同时比A'点和B'点到圆心的距离都大,也就是说,A'和B'两个点中,一定有一个是线段AB上距离圆心最远的坐标是整数的点。因此在枚举过程中,对于每一个x值,只要考察其对应的A'点和B'点即可。这样就大大减少了枚举的数据量和计算量。
·备注:
需要特别说明的是,在比较过程中,浮点型的数据类型由于表示精度的问题,不可以使用传统的<、>、==、>=、<=来作比较,可以根据精度的需要定义一个“极小数”,当两个浮点数的误差不超过这个“极小数”,就视为两数相同,具体如下:
以上是本题的解答思路。
输入输出格式:
输入:
One line with three floats which are all accurate to three decimal places, indicating the coordinates of the center x, y and the
radius r.
For 80% of the data: |x|,|y|<=1000, 1<=r<=1000
For 100% of the data: |x|,|y|<=100000, 1<=r<=100000
输出:
One line with two integers separated by one space, indicating the answer.
If there are multiple answers, print the one with the largest x-coordinate.
If there are still multiple answers, print the one with the largest y-coordinate.
程序代码:
HihoCoder1237
题目要求:
Given a circle on a two-dimentional plane.Output the integral point
in or on the boundary of the circle which has the largest distance from the center.
题目大意:
题目要求很简单:在二维坐标系中给定一个圆,要求找出在圆的范围内,x,y坐标都为整数的,距离圆心最远的点。如果存在多个点,则输出x坐标最大的点,如果依旧存在多个点,那么输出y坐标最大的点。
解答:
本题其实只要通过枚举就可以得出答案,因此难度不大。给定一个圆的圆心(x0, y0)和半径r,我们可以很容易地得到该圆在坐标系中的x坐标的范围,即:[x0 - r, x0 + r],由于所求点的左边只能是整数,因此,我们对这个区间的左右边界分别向上和向下取整,就是所求点的x坐标的范围,即:[ceil(x0-r), floor(x0+r)]。
确定x的范围后,我们对x从floor(x0+r)到ceil(x0-r)依次由大到小遍历整数值,对于给定的x,我们可以做出一条垂直于x轴的直线,直线和圆相交于两点,记为A,B,此时线段AB为圆的一条弦,如下图:
通过垂径定理,我们可以得到A,B点的坐标:
由于所求点的y坐标也必须为整数,因此,我们对A,B点的y坐标值也分别进行向下和向上取整,这样就得到了点A'和B',它们的坐标分别是:
显然,对于线段AB上的所有点,到圆心的距离一定比A点和B点要小。而对于线段AB上所有x坐标和y坐标均为整数的点,它到圆心的距离一定不可能同时比A'点和B'点到圆心的距离都大,也就是说,A'和B'两个点中,一定有一个是线段AB上距离圆心最远的坐标是整数的点。因此在枚举过程中,对于每一个x值,只要考察其对应的A'点和B'点即可。这样就大大减少了枚举的数据量和计算量。
·备注:
需要特别说明的是,在比较过程中,浮点型的数据类型由于表示精度的问题,不可以使用传统的<、>、==、>=、<=来作比较,可以根据精度的需要定义一个“极小数”,当两个浮点数的误差不超过这个“极小数”,就视为两数相同,具体如下:
double eps = 1e-6 -eps <= A - B <= eps => A == B A - B > eps => A > B A - B < -eps => A < B A - B >= -eps => A >= B A - B <= eps => A <= B
以上是本题的解答思路。
输入输出格式:
输入:
One line with three floats which are all accurate to three decimal places, indicating the coordinates of the center x, y and the
radius r.
For 80% of the data: |x|,|y|<=1000, 1<=r<=1000
For 100% of the data: |x|,|y|<=100000, 1<=r<=100000
输出:
One line with two integers separated by one space, indicating the answer.
If there are multiple answers, print the one with the largest x-coordinate.
If there are still multiple answers, print the one with the largest y-coordinate.
程序代码:
import static java.lang.Math.*; import java.util.Scanner; /** * This is the ACM problem solving program for hihoCoder 1237. * * @version 2016-08-18 * @author Zhang Yufei. */ public class Main { // input data. private static double x, y; private static double r; /** * The main program. * * @param args * The command line parameters. */ public static void main(String[] args) { Scanner scan = new Scanner(System.in); x = scan.nextDouble(); y = scan.nextDouble(); r = scan.nextDouble(); double max = -1; int max_x = -1, max_y = -1; double eps = 1e-6; for (int i = (int) floor(x + r); i >= (int) ceil(x - r); i--) { int top = (int) floor(y + sqrt(pow(r, 2) - pow(i - x, 2))); int bottom = (int) ceil(y - sqrt(pow(r, 2) - pow(i - x, 2))); double dist_top = pow(i - x, 2) + pow(top - y, 2); double dist_bottom = pow(i - x, 2) + pow(bottom - y, 2); if (max - dist_top < -eps) { max = dist_top; max_x = i; max_y = top; } if (max - dist_bottom < -eps) { max = dist_bottom; max_x = i; max_y = bottom; } } System.out.println(max_x + " " + max_y); scan.close(); } }
相关文章推荐
- ACM解题总结——HihoCoder1200 (微软笔试题)
- 微软笔试问题总结,吃一堑长一智
- 微软笔试总结
- 微软笔试总结
- 微软实习生笔试总结:
- 微软笔试总结之C++中char * 和 char []的区别,以及堆、栈
- ACM解题总结——HihoCoder1199 (微软笔试题)
- 微软2016校园招聘4月在线笔试 总结
- 9月26号微软笔试总结之sizeof
- 2013微软暑期实习笔试&面试总结
- 微软最新的一道笔试题,我觉的出的不好,要改的地方太多了
- 微软面试题总结版[zz]
- 微软ATC笔试题非正式招聘大程序题 选择自 huangkw007 的 Blog
- 微软笔试之反思(一)
- 微软笔试题3
- 去微软测试的总结——ACT(原创)
- 微软笔试之反思(二)
- 微软笔试题(zz)
- 【转载】微软笔试123
- C语言测试题目解答:微软一道笔试题,2005年华为招聘