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 }
时间: 2024-11-08 20:49:56

SOJ 1046 Plane Spotting的相关文章

Sicily 1046 Plane Spotting

1046. Plane Spotting Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description Craig is fond of planes. Making photographs of planes forms a major part of his daily life. Since he tries to stimulate his social life, and since it’s quite a drive

sicily 1046 Plane Spotting 快速排序解题

1046. Plane Spotting Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description Craig is fond of planes. Making photographs of planes forms a major part of his daily life. Since he tries to stimulate his social life, and since it’s quite a drive

sicily 1046. Plane Spotting(排序求topN)

DescriptionCraig is fond of planes. Making photographs of planes forms a major part of his daily life. Since he tries to stimulate his social life, and since it’s quite a drive from his home to the airport, Craig tries to be very efficient by investi

Sicily 1046. Plane Spotting 解题报告

1046_Plane_Spotting 题目链接: http://soj.me/1046 题目大意: 给出序号为1,2,3...的时间段和每段时间上出现的飞机次数,找出几个连续的时间段,如2-5,其中持续的长度要大于或者等于题目要求.按照以下的要求来筛选出几个最优的时间段,如果达到要求的数量不够则全部输出,符合以下要求视为时间段p1优于p2: p1平均每段时间出现的飞机数大于p2,要求精度是double 平均每段时间出现飞机数一样,但是p1的持续时间比p2长 平均每段时间出现飞机数一样且持续时间

编程题目分类(剪辑)

1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 11. 模拟 12. 算术与代数 13. 组合问题 14. 数论 15. 网格,几何,计算几何 [编程入门] PC 110101, uva 100, The 3n+1 problem, 难度 1 PC 110102, uva 10189, Minesweeper, 难度 1 PC 110103, uva 10137, The T

(转)sicily题目分类

Sicily题目分类 ·         [数据结构/图论] 1310 Right-Heavy Tree   笛卡尔树相关,复杂度O(N)或O(NlogN). ·1426 Phone List         电话号码前缀检索,trie树相关. ·1443 Printer Queue      基本队列操作. ·1149 等价表达式         判断表达式是否等价(递归求解) ·1136 山海经             n长序列里求m次区间询问的最大连续子区间和.线段树/RMQ ·1252

Soj题目分类

-----------------------------最优化问题------------------------------------- ----------------------常规动态规划  SOJ1162 I-Keyboard  SOJ1685 Chopsticks SOJ1679 Gangsters SOJ2096 Maximum Submatrix  SOJ2111 littleken bg SOJ2142 Cow Exhibition  SOJ2505 The County

BZOJ 1046: [HAOI2007]上升序列 LIS -dp

1046: [HAOI2007]上升序列 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3438  Solved: 1171[Submit][Status][Discuss] Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ax2 < … < axm).那么就称P为S的一个上升序列.如果有多

SOJ 4445 2015四川省赛模拟题

背景:赛场上就是因为没开这道题,而没拿到银,回来A了,感觉代码能力还是很弱,一定要先想好再敲,而且注重代码的函数化,这样无论是观感,还是调试都要好很多,逻辑要清晰,看代码要仔细,提交之前通读代码. 题意:起点在原点的frog,开始向右运动,且碰到障碍物就右转,问转多少次? 思路:关键是图的大小范围是109,无法存下,只有用类似链表的方法来存图.这里用了两个容器,一个以X为基准,一个一Y为基准,这两个容器设置很特殊,是为了满足题中特殊的查询需要:查询前进方向最近障碍物. 我的代码: #includ