繼上一篇博文《[創新工廠2014]迴文修復》後,繼續推出第二道創新工廠的筆試算法題~html
對於非負數列a一、a二、......、an,在數軸上作垂線鏈接點(i,0)和(i,ai)。選擇這樣的兩條線和x軸能夠造成一個容器,咱們以面積表明所裝的水,求以這種方式構成的容器能裝的最大面積。好比選擇a2=三、a5=6,則所裝的面積爲9。算法
分析:shell
這道題實際上的意思是:對於一個給定的序列,求abs(i-j)*min(a[i],a[j])的最大值!ide
先對序列按照高度排序,而後按照排序後的順序進行枚舉,枚舉過的就作標記,表示已經訪問過了,保證了當前的節點,是序列裏的最小高度的板,那麼以這個板爲邊界能裝的最大的水,確定就是當前序列的最左邊,或者最右邊,由於沒有其餘板比當前板更矮了,分別計算,而且update最大值。spa
若是當前這個節點就是邊界,且已經訪問過(即比當前的節點的高度更小),那麼就要對L和R進行收縮,保證L和R是當前節點能構成最大容器的最遠邊界。code
代碼以下:htm
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 }
若是有錯誤的地方,還望你們及時指出,謝謝~blog