pat1044
2013-10-11 20:49
302 查看
个人觉得这题非常的不错,对这类优化问题,个人非常的喜欢,大公司的面试题,很多也是这类优化问题,一般的方法大家都能想到,而好的方法却只有一部分人能想到。
这题其实就是让你在一串数中求连续的一段数,这段数的和减去给定值要尽量小(小到0最好),其实对这题最为有用的一个性质是这样的,假如我找到了一个Ai,A(i+1)......Aj 满足了要求,那么我下一次从i+1开始找的时候,我的j是不需要从i+2开始的,因为如果前面找到的是刚好等于的情况,即Ai+A(i+1)+...Aj=m,那么A(i+1)+...Aj肯定是小于m的所以我下一次的j只需要从j+1开始就好了,如果前面找到的是大于的情况,那么有Ai+A(i+1)+...Aj>m,那么我的j也从j+1开始可以吗?答案是不可以,因为有可能Ai很小,他们的和减去Ai仍旧符合大于m的性质,也就是说,A(i+1)
+...Aj也是大于m的,但是如果从j+1开始找,这个解被你忽略了,那么我j该从哪里开始呢,答案是从上次的j开始就好了,因为A(i+1) +...A(j-1)是不可能大于m的,因为Ai+A(i+1)+...A(j-1)是不大于m的,(如果,他们大于m,那么我不会等到j的时候才找到第一个满足条件的解,而是在j-1的时候就找到了),且A(i+1) +...A(j-1)<Ai+A(i+1)+...A(j-1),到此,这题个人感觉讲得比较清楚了,为了方便,我的代码中不管是找到等于的还是大于的,我的j都是从上次j开始找的,只是某些情况多找了一次,影响不大。另外这题需要s[i]记录前i个数的和,来实现新的j从上一次的j开始加的时候,来求的已经找到的和
代码如下:
这题其实就是让你在一串数中求连续的一段数,这段数的和减去给定值要尽量小(小到0最好),其实对这题最为有用的一个性质是这样的,假如我找到了一个Ai,A(i+1)......Aj 满足了要求,那么我下一次从i+1开始找的时候,我的j是不需要从i+2开始的,因为如果前面找到的是刚好等于的情况,即Ai+A(i+1)+...Aj=m,那么A(i+1)+...Aj肯定是小于m的所以我下一次的j只需要从j+1开始就好了,如果前面找到的是大于的情况,那么有Ai+A(i+1)+...Aj>m,那么我的j也从j+1开始可以吗?答案是不可以,因为有可能Ai很小,他们的和减去Ai仍旧符合大于m的性质,也就是说,A(i+1)
+...Aj也是大于m的,但是如果从j+1开始找,这个解被你忽略了,那么我j该从哪里开始呢,答案是从上次的j开始就好了,因为A(i+1) +...A(j-1)是不可能大于m的,因为Ai+A(i+1)+...A(j-1)是不大于m的,(如果,他们大于m,那么我不会等到j的时候才找到第一个满足条件的解,而是在j-1的时候就找到了),且A(i+1) +...A(j-1)<Ai+A(i+1)+...A(j-1),到此,这题个人感觉讲得比较清楚了,为了方便,我的代码中不管是找到等于的还是大于的,我的j都是从上次j开始找的,只是某些情况多找了一次,影响不大。另外这题需要s[i]记录前i个数的和,来实现新的j从上一次的j开始加的时候,来求的已经找到的和
代码如下:
#include<stdio.h> #define inf 0x7FFFFF int a[100001]; int s[100001]; int ans[10001][2]; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { int i,j,k; s[0]=0; for(i=1;i<=n;i++) { scanf("%d",a+i); s[i]=s[i-1]+a[i]; } int find=0; int sum; int flag=0; int cl; int laj; int cnt=0; int min=s ; for(i=1;i<=n;i++) { if(find==0) { cl=i; sum=0; } else { cl=laj; sum=s[laj-1]-s[i-1]; } for(j=cl;j<=n;j++) { sum+=a[j]; if(sum>=m) { find=1; if(sum-m<min) { min=sum-m; cnt=1; ans[1][0]=i; ans[1][1]=j; } else if(sum-m==min) { cnt++; ans[cnt][0]=i; ans[cnt][1]=j; } laj=j; break; } } } for(i=1;i<=cnt;i++) printf("%d-%d\n",ans[i][0],ans[i][1]); } }
相关文章推荐
- 面向对象——单例设计模试
- Eclipse开发android程序xml不提示
- Object-C属性访问
- Crazy_Javar之反射--->ObjectPoolFactory
- Flex组件Repeater
- 《算法导论(第二版)》习题22.1-6:图的通用汇点(Universal Sink)
- 华为三层交换机配置方法
- adb server is out of date. killing... ADB server didn't ACK解决方法
- HDU 4572 Bottles Arrangement找规律 简单题
- 《转载》hadoop cdh3u3 eclipse插件编译
- 包含min操作的栈
- linux下pthread_exit在主线程中的用途
- 一个 C# 获取高精度时间类(调用API QueryP*)
- Red hat linux ping: unknown host www.baidu.com
- vim安装之后不能高亮显示
- 一道简单的算法练习题试水下
- makefile 书写规则三 文件搜寻
- 二叉堆
- 初学hadoop之--------java中的for each语句----for (IntWritable val : values)
- cannot restore segment prot after reloc: Permission denied