[创新工场2014] 2014创新工场校园招聘笔试题
2013-09-26 16:42 庸男勿扰 阅读(1851) 评论(8) 编辑 收藏 举报继上一篇博文《[创新工厂2014]回文修复》后,继续推出第二道创新工厂的笔试算法题~
对于非负数列a1、a2、......、an,在数轴上做垂线连接点(i,0)和(i,ai)。选择这样的两条线和x轴可以形成一个容器,我们以面积代表所装的水,求以这种方式构成的容器能装的最大面积。比如选择a2=3、a5=6,则所装的面积为9。
分析:
这道题实际上的意思是:对于一个给定的序列,求abs(i-j)*min(a[i],a[j])的最大值!
先对序列按照高度排序,然后按照排序后的顺序进行枚举,枚举过的就做标记,表示已经访问过了,保证了当前的节点,是序列里的最小高度的板,那么以这个板为边界能装的最大的水,肯定就是当前序列的最左边,或者最右边,因为没有其他板比当前板更矮了,分别计算,并且update最大值。
如果当前这个节点就是边界,且已经访问过(即比当前的节点的高度更小),那么就要对L和R进行收缩,保证L和R是当前节点能构成最大容器的最远边界。
代码如下:
1 #include <cstdio> 2 #include <cstdlib> 3 #include <algorithm> 4 #include <limits.h> 5 using namespace std; 6 7 #define max(a,b) a>b?a:b 8 9 typedef struct Pair{ 10 int i; 11 int ai; 12 }Pair; 13 Pair p[101]; 14 15 int n; 16 17 int flag[101]; 18 19 bool cmp(Pair a,Pair b) 20 { 21 if(a.ai<b.ai) 22 return true; 23 else 24 return false; 25 } 26 int main() 27 { 28 freopen("b3.in","r",stdin); 29 freopen("b3.out","w",stdout); 30 31 int maxRes; 32 int L,R; 33 while(scanf("%d",&n)!=EOF) 34 { 35 memset(flag,0,sizeof(flag)); 36 maxRes = INT_MIN; 37 for(int i=0; i<n; i++) 38 { 39 scanf("%d",&p[i].ai); 40 p[i].i = i; 41 } 42 sort(p,p+n,cmp); 43 L=0; 44 R=n-1; 45 for(int i=0; i<n; i++) 46 { 47 flag[p[i].i] = 1; 48 maxRes = max(maxRes,abs(L-p[i].i)*p[i].ai); 49 maxRes = max(maxRes,abs(R-p[i].i)*p[i].ai); 50 51 if(p[i].i==L) 52 { 53 while(flag[L]==1) L++; 54 } 55 if(p[i].i==R) 56 { 57 while(flag[R]==1) R--; 58 } 59 } 60 61 printf("%d\n",maxRes); 62 63 } 64 return 0; 65 }
如果有错误的地方,还望大家及时指出,谢谢~
作者:庸男勿扰
出处:http://www.cnblogs.com/codershell
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如果您觉得对您有帮助,不要忘了推荐一下哦~
出处:http://www.cnblogs.com/codershell
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如果您觉得对您有帮助,不要忘了推荐一下哦~