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 from his home to the airport, Craig tries to be very efficient by investigating what the optimal times are for his plane spotting. Together with some friends he has collected statistics of the number of passing planes in consecutive periods of fifteen minutes (which for obvious reasons we shall call ‘quarters’). In order to plan his trips as efficiently as possible, he is interested in the average number of planes over a certain time period. This way he will get the best return for the time invested. Furthermore, in order to plan his trips with his other activities, he wants to have a list of possible time periods to choose from. These time periods must be ordered such that the most preferable time period is at the top, followed by the next preferable time period, etc. etc. The following rules define which is the order between time periods:

1. A period has to consist of at least a certain number of quarters, since Craig will not drive three hours to be there for just one measly quarter. 
2. A period P1 is better than another period P2 if: 
* the number of planes per quarter in P1 is higher than in P2; 
* the numbers are equal but P1 is a longer period (more quarters); 
* the numbers are equal and they are equally long, but period P1 ends earlier.

Now Craig is not a clever programmer, so he needs someone who will write the good stuff: that means you. So, given input consisting of the number of planes per quarter and the requested number of periods, you will calculate the requested list of optimal periods. If not enough time periods exist which meet requirement 1, you should give only the allowed time periods.

 

Input

The input starts with a line containing the number of runs N. Next follows two lines for each run. The first line contains three numbers: the number of quarters (1–300), the number of requested best periods (1–100) and the minimum number of quarters Craig wants to spend spotting planes (1–300). The sec-nod line contains one number per quarter, describing for each quarter the observed number of planes. The airport can handle a maximum of 200 planes per quarter.

Output

The output contains the following results for every run: 

* A line containing the text “Result for run <N>:” where <N> is the index of the run. 

* One line for every requested period: “<F>-<L>” where <F> is first quarter and <L> is the last quarter of the period. The numbering of quarters starts at 1. The output must be ordered such that the most preferable period is at the top.

Sample Input

3
10 5 5
1 5 0 2 1 4 2 5 0 2 
10 3 5
10 3 1 4 2 6 3 0 8 0 
5 5 5
1 2 3 4 5

Sample Output

Result for run 1:
4-8
2-8
6-10
1-8
2-6
Result for run 2:
1-6
1-7
1-9
Result for run 3:
1-5

 

这道题虽然题目比较长,但将题目的情境转换为具体的要求后还是比较简单的。每次给出三个数字n、m、s,分别表示题目给出序列中的数字个数、需要输出的序列个数、每一个子序列的最小长度。题目要求,找出题目给出序列的所有连续子序列中,前m个长度按照优先级排序、长度不小于m的子序列,每个子序列以“序列开始元素-序列末尾元素”的形式表示。

优先级顺序为:

若两个序列平均值不同,则平均值大的优先;

若两个序列平均值相同,则长度大的优先;

若两个序列平均值相同且长度相同,则序列末尾元素靠前的优先。

首先定义结构体p储存每一个符合要求的连续子序列的平均值、长度、末尾元素的位置,然后双重循环遍历所有连续子序列,若序列长度大于等于m满足要求,则将该子序列的平均值、长度、末尾元素的位置存入结构体中,并使用计数器counter记录序列个数;

然后自定义cmp(const node &a,const node &b)对所有符合要求的子序列进行排序,首先判断平均值,如果两平均值之差在误差范围外,则返回a.ave>b.ave;如果平均值在误差范围内,则判断长度,返回a.length>b.length;最后如果平均值和长度均无法判断优先级,则判断序列末尾元素的位置,返回a.end<b.end,然后对结构体数组p进行sort排序即可;

最后按照题目要求输出时,需要注意,我们的得到的符合要求的连续子序列的个数不一定大于等于m,有可能小于m,所有需要做一个判断,如果counter>=m,则输出m个序列;如果counter<m,则输出counter个序列即可。

代码如下:

#include <iostream>
#include <cstring>
#include <algorithm> 
#include <cmath>
using namespace std;
double a[306]={0};
double sum[306]={0};
struct node
{
	double ave;
	int length;
	int end;
}p[100006];

bool cmp(const node &a,const node &b)
{
	if(fabs(a.ave-b.ave)>0.000000001) return a.ave>b.ave;
	else if(a.length!=b.length)       return a.length>b.length;
	else                              return a.end<b.end; 
}

int main()
{
	int T;
	cin>>T;
	for(int t=1;t<=T;t++)
	{
		int n,m,s;
		cin>>n>>m>>s;

		memset(a,0,sizeof(a));
		memset(sum,0,sizeof(sum));

		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
			sum[i]=sum[i-1]+a[i];
		}
		int counter=0;
		for(int i=1;i<=n;i++)
		{
			for(int j=i;j<=n;j++)
			{
				if(j-i+1>=s)
				{
					p[counter].ave=(sum[j]-sum[i-1])/(j-i+1);
					p[counter].length=j-i+1;
					p[counter].end=j;
					counter=counter+1;
				}
			}
		}
		sort(p,p+counter,cmp);
		cout<<"Result for run "<<t<<":"<<endl;
		
		int temp;
		if(counter<m) temp=counter;
		else temp=m;
		for(int i=0;i<temp;i++)
		{			
			cout<<p[i].end-p[i].length+1<<"-"<<p[i].end<<endl;
		}

	}
	return 0;
}

  

转载于:https://www.cnblogs.com/RiTianBigBrother/p/5309337.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值