您的位置:首页 > 其它

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'点即可。这样就大大减少了枚举的数据量和计算量。

·备注:

    需要特别说明的是,在比较过程中,浮点型的数据类型由于表示精度的问题,不可以使用传统的<、>、==、>=、<=来作比较,可以根据精度的需要定义一个“极小数”,当两个浮点数的误差不超过这个“极小数”,就视为两数相同,具体如下:
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();
}
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息