计蒜之道2015程序设计大赛初赛第三场——腾讯手机地图

(一)题面

腾讯手机地图的定位功能用到了用户手机的多种信号,这其中有的信号的作用范围近,有的信号作用的范围则远一些。有的信号相对于用户在不同的方位强度是不同的,有的则是在任何一个方向上信号强度都一致的。

已知用户面向北方拿着自己的手机,在不同方位的各种信号覆盖区域可以被抽象成以用户为圆心的一系列扇形。已知每个扇形的半径 r,和每个扇形的两条边相对于正东方向的夹角度数。每个信号覆盖区域抽象出的扇形都可以通过从第一条边逆时针旋转到第二条边画出。

请计算一下,用户手机所有信号覆盖到的区域的总面积。

输入格式

第一行输入一个整数 T (1 ≤ T ≤ 20),表示数据组数。

接下来一共 T 组数据,每组数据第一行输入一个整数 n (1 ≤ n ≤ 104),表示各种信号可以抽象出的不同扇形的总个数。接下来输入 n 行,每行 3 个整数表示扇形半径 r (0 ≤ r ≤ 105)、扇形第一条边与正东方向的夹角 α、扇形第二条边与正东方向的夹角 β (-90 ≤ α ≤ β < 270)。

输出格式

输出 T 行,每行一个非负浮点数,表示用户手机所有信号覆盖到的区域的范围的总面积。

每组输出与标准答案绝对误差在 10-3 内均认为是正确的。

样例1

输入:

1
4
2 -30 32
3 20 81
3 121 160
2 141 201

输出:

11.030

(二)参考源码

 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStreamReader;
 4 import java.text.DecimalFormat;
 5 import java.util.Arrays;
 6 
 7 public class Main {
 8     private static final BufferedReader READER = new BufferedReader(
 9             new InputStreamReader(System.in));
10     private static final DecimalFormat _0_000 = new DecimalFormat("0.000");
11 
12     private static int readInt() throws IOException {
13         return Integer.parseInt(READER.readLine());
14     }
15 
16     private static int[] readIntArray() throws IOException {
17         String[] stringArray = READER.readLine().split(" ");
18         int[] intArray = new int[stringArray.length];
19         for (int i = 0; i < stringArray.length; i++) {
20             intArray[i] = Integer.parseInt(stringArray[i]);
21         }
22         return intArray;
23     }
24 
25     public static void main(String[] args) throws Exception {
26         int testCount = readInt();
27         int[] degreeArray = new int[361];
28         while (testCount-- > 0) {
29             long area = 0;
30             Arrays.fill(degreeArray, 0);
31             int lineCount = readInt();
32             while (lineCount-- > 0) {
33                 int[] intArray = readIntArray();
34                 for (int i = intArray[1]; i < intArray[2]; i++) {
35                     int j = i + 90;
36                     if (degreeArray[j] < intArray[0]) {
37                         degreeArray[j] = intArray[0];
38                     }
39                 }
40 
41             }
42             for (int i = 0; i < 360;) {
43                 int r = degreeArray[i];
44                 if (r == 0) {
45                     i++;
46                     continue;
47                 }
48                 int begin = i;
49                 int end = i + 1;
50                 for (int j = end; j < 361; j++) {
51                     if (degreeArray[j] != r) {
52                         end = j;
53                         break;
54                     }
55                 }
56                 // r虽然是整数范围的,但是(end -
57                 // begin)*r*r会超过整数的范围,所以计算时,先将(end-begin)转化成long
58                 area += (long) (end - begin) * r * r;
59                 i = end;
60             }
61             System.out.println(_0_000.format(area * Math.PI / 360));
62         }
63     }
64 }
Java