SOJ 1046 Plane Spotting

题目大意:输入整数t,表示有t组测试样例。每组测试样例首先输入三个整数,分别是n(1 ≤ n ≤300)表示有n个观测飞机的时刻,l(1 ≤ l ≤ 100)表示输出结果中的的最高l组,m(1 ≤ m ≤ 300)表示时刻区间的最少包含区间数。接着输入n个整数,分别代表每个时刻可观测的飞机数,计作pi(1 ≤ i ≤ n)。求解满足最少区间要求的区间中平均时刻能观测飞机数最多的l组区间。

其他条件:

区间pi比pj好的条件是:

1.pi区间平均时刻飞机数多余pj区间

2.若平均时刻飞机数相同,则需要pi区间大于pj区间

3.若平均时刻飞机数相同写,区间大小相同,则需要pi比p早完成。

输出格式:

  先输出"Result for run #:",其中#表示第几组测试样例,从1开始。

  再输出最高l组区间,"{from}-{to}",{from}表示区间开始,{to}表示区间结束。

 

解题思路:首先选出所有满足最少时刻数要求的区间,然后对每个区间进行排序比较。最后最高的l组结果,如果满足要求的区间不足l组,则按顺序输出全部顺序。

     考虑到求区间和,想起了前缀和,这是一个小小的优化。

代码如下:

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int maxn = 305;
 7 int arr[maxn];
 8 int sum[maxn];
 9 
10 struct Interval {
11     int from;
12     int to;
13     Interval(int f = 0, int t = 0) {
14         from = f;
15         to = t;
16     }
17 };
18 
19 bool cmpFunc(const Interval & i1, const Interval & i2) {
20     bool swap;
21     double s1 = (sum[i1.to] - sum[i1.from - 1] + 0.0) / (i1.to - i1.from + 1);
22     double s2 = (sum[i2.to] - sum[i2.from - 1] + 0.0) / (i2.to - i2.from + 1);
23     if (s1 > s2) {
24         swap = false;
25     } else if (s1 < s2) {
26         swap = true;
27     } else {
28         int l1 = i1.to - i1.from + 1;
29         int l2 = i2.to - i2.from + 1;
30         if (l1 > l2) {
31             swap = false;
32         } else if (l1 < l2) {
33             swap = true;
34         } else {
35             if (i1.to > i2.to) {
36                 swap = true;
37             } else if (i1.to < i2.to) {
38                 swap = false;
39             } else {
40                 cout << "error this time" << endl;
41             }
42         }
43     }
44     return !swap;
45 }
46 
47 int main() {
48     int t, n, l, m;
49     
50     cin >> t;
51     for (int tt = 1; tt <= t; tt++) {
52         vector<Interval> vt;
53         cin >> n >> l >> m;
54 
55         // 获取每时刻的飞机数
56         arr[0] = sum[0] = 0;
57         for (int i = 1; i <= n; i++) {
58             cin >> arr[i];
59             sum[i] = 0;
60         }
61 
62         // 计算前缀和
63         for (int i = 1; i <= n; i++) {
64             sum[i] = sum[i - 1] + arr[i];
65         }
66 
67         // 获得所有可行的区间
68         for (int i = 1; i + m - 1 <= n; i++) {
69             for (int j = i + m - 1; j <= n; j++) {
70                 vt.push_back(Interval(i, j));
71             }
72         }
73 
74         // 对区间信息进行排序
75         sort(vt.begin(), vt.end(), cmpFunc);
76 
77         // 输出结果
78         cout << "Result for run " << tt << ":" << endl;
79         int c = l > vt.size() ? vt.size() : l;
80         for (int i = 0; i < c; i++) {
81             cout << vt[i].from << "-" << vt[i].to << endl;
82         }
83 
84     }
85 
86     return 0;
87 }

 

posted @ 2015-09-24 14:07  MchCyLh  阅读(177)  评论(0编辑  收藏  举报