Sicily 1046. Plane Spotting 解题报告
1046_Plane_Spotting
题目链接:
题目大意:
给出序号为1,2,3...的时间段和每段时间上出现的飞机次数,找出几个连续的时间段,如2-5,其中持续的长度要大于或者等于题目要求。按照以下的要求来筛选出几个最优的时间段,如果达到要求的数量不够则全部输出,符合以下要求视为时间段p1优于p2:
- p1平均每段时间出现的飞机数大于p2,要求精度是double
- 平均每段时间出现飞机数一样,但是p1的持续时间比p2长
- 平均每段时间出现飞机数一样且持续时间一样,p1结束时间早于p2
思路:
可以找出所有可能符合要求的时间段,然后根据题目的规则来进行排序,将最前的所要求的个数输出即可。这里用Period结构体来存储数据比较方便,而且考虑到存储时间段的数组需要动态分配大小,所以这里用vector实现。
要找出所有可能符合要求的连续时间段,左端点从1开始截取,对于每个左端点,右端点可以从要的的最短长度直到最后的一个时间段,算出每个连续时间段的平均飞机出现次数,然后可以通过sort函数进行排序,注意自己设置compare函数。
代码:
#include <iostream> #include <vector> #include <algorithm> using namespace std; struct Period{ int start_quarter; int end_quarter; double average; Period(int s = 1, int e = 1, double a = 1){ start_quarter = s; end_quarter = e; average = a; } }; void calculate_periods(vector<Period> &periods, int *num_planes, int num_quarters, int min_quarters); bool compare(const Period &p1, const Period &p2); void display_periods(vector<Period> periods, const int num_requested, const int min_quarters); int main(){ int n; cin >> n; for (int run_num = 1; run_num <= n; ++run_num) { int num_quarters, num_requested, min_quarters; cin >> num_quarters >> num_requested >> min_quarters; vector<Period> periods; int num_planes[num_quarters + 1]; for (int i = 1; i <= num_quarters; ++i) { cin >> num_planes[i]; } calculate_periods(periods, num_planes, num_quarters, min_quarters); sort(periods.begin(), periods.end(), compare); cout << "Result for run " << run_num << ":" << endl; display_periods(periods, num_requested, min_quarters); } return 0; } void calculate_periods(vector<Period> &periods, int *num_planes, int num_quarters, int min_quarters){ for (int i = 1; i <= num_quarters - min_quarters + 1; ++i) { int total = 0; for (int j = i; j <= num_quarters; ++j) { total += num_planes[j]; if(j - i + 1 >= min_quarters) periods.push_back(Period(i, j, ((double)total) / ((double)(j - i + 1)))); } } } void display_periods(vector<Period> periods, const int num_requested, const int min_quarters){ for (int i = 0; i < num_requested; ++i) { unsigned int i_unsigned = i; if(i_unsigned < periods.size()) cout << periods[i].start_quarter << "-" << periods[i].end_quarter << endl; } } bool compare(const Period &p1, const Period &p2){ if(p1.average < p2.average) return false; else if(p1.average == p2.average){ if(p1.end_quarter - p1.start_quarter < p2.end_quarter - p2.start_quarter) return false; else if(p1.end_quarter - p1.start_quarter == p2.end_quarter - p2.start_quarter){ return p1.end_quarter < p2.end_quarter; } else return true; } else return true; }