第三章 数组与字符串 UVa1588 Kickdown

题目要求简述:给定长度分别为n1,n2(n1,n2<=100)且每列的高度只为1或者2的长条。需要将他们放入一个高度为3的容器,问能够容纳它们的最短容器长度。

分析:

  1. 对于这样的题目显而易见有两种思路,第一,固定一个字符串,另一个从左到右进行移动。第二,固定一个字符串a,字符串b移动,再固定b,让a移动,取二者长度最小值。
  2. 两种方法我都经过自己的实现,觉得还是第二种代码更简洁优雅,同时还具有一定的可扩展性。

用例子说明一下吧~

数组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

 

posted @ 2016-06-06 19:23  仰望高端玩家的小清新  阅读(2458)  评论(1编辑  收藏  举报