算法:模拟法二(杭电ACM4816)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chekongfu/article/details/51754958

Bathysphere

Time Limit: 20000/10000 MS(Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 707    Accepted Submission(s): 139

Problem Description

The Bathysphere is a spherical deep-sea submersible whichwas unpowered and lowered into the ocean on a cable, and was used to conduct aseries of dives under the sea. The Bathysphere was designed for studyingundersea wildlife.

The Bathysphere was conducted from the deck of a ship. After counted, the shipshould not move, so choosing the position where the Bathysphere was conductedis important.

A group of scientists want to study the secrets of undersea world along theequator, and they would like to use the Bathysphere. They want to choose theposition where the Bathysphere can dive as deep as possible. Before conductingthe Bathysphere, they have a map of the seabed, which tell them the shape ofthe seabed. They draw a line on the equator of the map to mark where they willrelease the Bathysphere, as a number axis. Suppose the axis is draw from 0 toL. But when they release the Bathysphere, they can't know where they areaccurately, i.e., if they choose position x to release the Bathysphere, thereal position will distribute between x-d and x+d with an equal probability,where d is given. The objective of the scientists is very simple, i.e., tomaximize the expected depth.

For the ease of presentation, the shape of the seabed is described as a polyline. Given N points ) , ( Xi,Yi ) as the vertices, whereXi and Yi indicate the position and the depth of the i-thvertex, respectively, the ploy line is composed of the line segments thatconnect consecutive vertices.

 

 

Input

The first line contains an integer T (1 ≤ T ≤ 25), thenumber of test cases.

Then T test cases follow. In each test case, the first line contains twointegers N (2 ≤ N ≤ 2*10^5) and L (2 ≤ L ≤ 10^9), as described above. Then Nlines follow, each line contains two integer Xi and Yi(1≤i≤N, 0≤ Yi ≤10^9), where point ( Xi,Yi ) isa vertex of the ploy line. It is assumed that X1 == 0 and Xn== L and Xi < Xi+1 for 1 ≤ i < N. Then thefollowing line contains one integer d (0 ≤ d ≤ L/2), as described above.

 

 

Output

For each test case, choose a position between d and L-d,both inclusive, to conducted the Bathysphere, and calculate the expected depth.Output the expected depth in a line, rounded to 3 digits after the decimalpoint.

 

 

Sample Input

2

3 10

0 3

4 10

10 1

5

3 10

0 3

4 10

10 1

1

 

 

Sample Output

5.900

9.192

 

作者贴出自己的答案如下:

 

package arithmetic.simulation;
 
import java.text.DecimalFormat;
import java.util.Scanner;
 
public class Bathysphere {
  
   public static void main(String[] args) throws Exception {
      Scanner sc = new Scanner(System.in);
      int cases = sc.nextInt(); //总人数
      while(cases>0){
         int N = sc.nextInt(); //N个点
         int L = sc.nextInt(); //线条长度
         int[][] points = new int[N][2];
         double[] ks = new double[N-1];  //斜率
        
         for(int i=0; i<N; i++){
            points[i][0] = sc.nextInt();
            points[i][1] = (-1)*sc.nextInt();
           
            if(i>0){
                if( points[i][0] > L || points[i][0] < points[i-1][0]) {
                   throw new Exception("输入不符合要求");
                }
               
                ks[i-1] =(points[i][1]-points[i-1][1])*1.0000/(points[i][0]-points[i-1][0]) ;
            }
         }
         int d = sc.nextInt(); //误差半径
         System.out.println();
        
         double maxArea = 0.0 ;
         for(double offset = 0; offset+2*d<=L;){
            double area = getArea(points, ks, offset, d);
            if(maxArea<area){
                maxArea = area ;
            }
            offset += 0.001 ;
         }
        
         DecimalFormat df = new DecimalFormat("#.000");
        
         System.out.println();
         System.out.print( df.format( maxArea/(2*d) ) );
         cases--;
      }
   }
  
   public static double getArea(int points[][], double ks[], double offset, int d){
      double x1=offset, x2=offset+2*d, y1=0.0, y2=0.0 ;
      int count = 0 ;
      double[][] ps = new double[points.length][2];
      double area = 0.0 ;
     
      for(int i=0; i<points.length; i++){
         if(points[i][0]<=x1 && x1<points[i+1][0]){
            y1 = ks[i]*(x1-points[i][0]) + points[i][1] ;
            ps[count][0] = x1 ;
            ps[count][1] = y1 ;
            count++;
           
            if(points[i][0]<=x2 && x2<=points[i+1][0]){
                y2 = ks[i]*(x2-points[i][0]) + points[i][1] ;
                ps[count][0] = x2 ;
                ps[count][1] = y2 ;
                break;
            }
         } else if(points[i][0]<=x2 && x2<=points[i+1][0]){
            ps[count][0] = points[i][0] ;
            ps[count][1] = points[i][1] ;
            count++;
           
            y2 = ks[i]*(x2-points[i][0]) + points[i][1] ;
            ps[count][0] = x2 ;
            ps[count][1] = y2 ;
            break;
         } else if (x1 < points[i][0] && points[i+1][0] < x2){
            ps[count][0] = points[i][0] ;
            ps[count][1] = points[i][1] ;
            count++;
         }
         //count++;      //这行加上会犯大错,这行只能在带else的逻辑中添加
      }
     
      for(int j=0; j<count; j++){
         area += (-1)*(ps[j][1] + ps[j+1][1])*(ps[j+1][0]-ps[j][0]) /2 ;
      }
  
      return area ;
   }
}


作者总结如下:

1、 首先要审题,尤其是像作者这样英语渣,前期花了大量时间审题,搞清题意;

2、 找思路,开始不要考虑算法性能问题,最重要的是解决问题,其次验证正确性

3、 最后再考虑性能,看内存,时间是否还有提升空间

4、 在杭电的ACM系统中提交结果为W,可以用C/C++按照既定思路实现一遍

 

版权声明:本文为作者原创文章,未经作者允许不得转载。文章内容如有不妥之处,请留言指出,以作讨论。

猜你喜欢

转载自blog.csdn.net/chekongfu/article/details/51754958
今日推荐