題目要求簡述:給定長度分別為n1,n2(n1,n2<=100)且每列的高度只為1或者2的長條。需要將他們放入一個高度為3的容器,問能夠容納它們的最短容器長度。
分析:
- 對於這樣的題目顯而易見有兩種思路,第一,固定一個字符串,另一個從左到右進行移動。第二,固定一個字符串a,字符串b移動,再固定b,讓a移動,取二者長度最小值。
- 兩種方法我都經過自己的實現,覺得還是第二種代碼更簡潔優雅,同時還具有一定的可擴展性。
用例子說明一下吧~
數組1和數組2是我們待比較的兩個數組,(當然,都是字符串數組),我們先固定其中的任意一個,放在下方,在讓另一個在上方不斷向左平移,進行比較,即可
當初次比較時,有如下圖例
此時,從數組1的頭元素開始和數組2的頭元素進行比較,當出現兩個2,或者匹配部分比較完成時,此次比較完成,用一個狀態變量標記此次比較的結果。
由圖例知,此次比較會停止在下標為1的元素上。
然后上面的數組下標右移,相當於數組左移,進行第二次比較。
由圖例知,此次比較是成功的,用兩個數組的總長度n1+n2減去匹配部分的長度,即得到此次所需的長度len,如果len小於原先記錄的最小長度,則更新最小長度。
不斷重復上述過程,直到這種情況為止:
這樣我們就完成一半的比較任務,接下來,就是將數組1和數組2的位置顛倒,重復上述過程,取兩次所得最小值,即可得到最終結果
顛倒並重復上述過程:
明白了思路,接下來讓我們給出一個簡潔的代碼實現:
1 #include<cstdio> 2 #include<cstring> 3 const int maxn=100; 4 char a[maxn+1],b[maxn+1]; 5 int n1,n2; 6 int min(const int &i,const int &j){ 7 return i<j?i:j; 8 } 9 int minLen(char *s1,char *s2,int &n){// n為s1的長度 10 int sumLen=n1+n2,minn=min(n1,n2),len=sumLen; 11 for(int i=0;i<n;i++){ 12 int ok=1,fix=min(n-i,minn);//fix的計算是一個難點 13 for(int j=0;j<fix;j++)if(s1[i+j]=='2'&&s2[j]=='2'){ 14 ok=0;break; 15 } 16 if(ok&&len>sumLen-fix)len=sumLen-fix; 17 } 18 return len; 19 } 20 int main(){ 21 while(scanf("%s%s",&a,&b)==2){ 22 n1=strlen(a),n2=strlen(b);//無意中用到了逗號運算符 23 printf("%d\n",min(minLen(a,b,n1),minLen(b,a,n2)));//用min函數取兩次結果的最小值 24 } 25 }
好啦,今天就到這里,貼一下戰果以及傳送門,大家加油哦~~~,拜拜\(•ω•`)o
題目傳送門:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4463