近来为参加百度之星编程赛,找到往年的试题做做,到网上
- #include <stdio.h>
- #include <stdlib.h>
- int number[100]; //保存员工的满意度
- int n; //保存最小覆蓋区域数
- int m; //保存总的区域数
- float result = 0; //最大平均和
- int x,y; //最大平均和的起始和终止位置
- void func(int start,int end);
- int main(){
- int i;
- printf("input:\n");
- scanf("%d %d",&m,&n);
- for(i = 0;i < m;i ++){
- scanf("%d",&number[i]);
- }
- func(0,m-1);
- printf("result=%f start=%d end=%d n=%d\n",result,x,y,y-x+1);
- system("pause");
- }
- void func(int start,int end){
- printf("start=%d end=%d\n",start,end);
- if(end - start + 1 < n) return;
- float fresult;
- int i,fsum,fx,fy;
- fsum = 0,fx = start,fy = start+n-1;
- for(i = 0;i < n;i ++){
- fsum += number[start+i];
- }
- for(i = fy+1;i < m;i ++){
- fresult = (float)fsum/(fy-fx+1);
- printf("%d %f\n",fsum,fresult);
- if( fresult > result){
- result = fresult;
- x = fx;
- y = fy;
- }
- if( number[start] < fresult){
- fsum -= number[start];
- fx ++;
- }
- fy ++;
- fsum += number[fy];
- }
- fresult = (float)fsum/(fy-fx+1);
- if( fresult > result){
- result = fresult;
- x = fx;
- y = fy;
- }
- func(fx+1,fy);
- }
搜答案时发现找不到这方面的解答,故写出自己的一些解法,希望对大家有所帮助,不喜勿喷。。。
题目:
园艺布置 时间限制
:1000ms 描述
近期,百度采纳了员工们的提议,计划在总部大楼内部种植园艺,以提供更加温馨的工作环境。公司将园艺设计的任务交给了度度熊同学。
公司总部大楼内部的构造可以分为
n
个区域,编号为0, 1, …,
n
–1
,其中区域
i
与
i
+ 1
是相邻的(0 ≤
i
<
n
– 1
)。根据员工的投票和反馈,度度熊拿到了一份数据,表明在区域
i
种植园艺可以获得员工的满意度为
Ai
。度度熊希望园艺的布置方案满足条件:
1.
至少覆蓋
m
个区域;
2.
布置园艺的区域是连续的。
请帮他找到一种满足条件的方案,使布置园艺区域的员工的满意度的平均值最大。 输入
输入的第一行包含两个整数
n
和
m
,分别表示总区域数和至少覆蓋的区域数。
第二行包含
n
个整数
A
0
,
A
1
,…,
An
– 1
,依次表示在每个区域种植园艺可以获得员工的满意度。 输出
输出一行,表示员工的平均满意度的最大值。如果这个数是一个整数,则直接按整数格式输出;否则,请用最简分数表示,分子分母以“/”分割,格式见样例。 样例输入
样例输入1
3 1
2 3 1
样例输入2
5 3
1 8 2 4 8
样例输出
样例输出1
3
样例输出2
11/2
提示
样例2的正确答案为11/2,尽管22/4数值也相同,但由于没有化简,所以是错误的。
对于100%的数据,1 ≤
m
≤
n
≤ 106
,1 ≤
Ai
≤ 106
。
解题思路:首先这是一个很大的数(106),如果采用一般的方法就会106*106时间上不够,故需要采用一些优化方法。。。。
“我们不能看到将来会发生什么,但是我们能够对过去发生的事情进行分析来应对将来发生的事情!”我们可以采用下述方法来优化我们的算法。首先我们以一个断点(START)为起点,往后先计算出最少区域的平均和(AVG),在遍历下一个数,如果这个START比AVG小,则将端点向前移动一位,同时加上后一个数,再求出AVG,继续上一步操作。直到最后一个满意度。这样我们就把这个满意度的范围缩小了很多,继续上述步骤。。。。
如图:
附上代码: