第三章 数组与字符串 UVa1588 Kickdown
题目要求简述:给定长度分别为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