Uva1588
A research laboratory of a world-leading automobile company has received an order to create a special transmission mechanism, which allows for incredibly efficient kickdown — an operation of switching to lower gear. After several months of research engineers found that the most efficient solution requires special gears with teeth and cavities placed non-uniformly. They calculated the optimal flanks of the gears. Now they want to perform some experiments to prove their findings. The first phase of the experiment is done with planar toothed sections, not round-shaped gears. A section of length n consists of n units. The unit is either a cavity of height h or a tooth of height 2h. Two sections are required for the experiment: one to emulate master gear (with teeth at the bottom) and one for the driven gear (with teeth at the top).
There is a long stripe of width 3h in the laboratory and its length is enough for cutting two engaged sections together. The sections are irregular but they may still be put together if shifted along each other.
The stripe is made of an expensive alloy, so the engineers want to use as little of it as possible. You need to find the minimal length of the stripe which is enough for cutting both sections simultaneously.
Input
The input file contains several test cases, each of them as described below. There are two lines in the input, each contains a string to describe a section. The first line describes master section (teeth at the bottom) and the second line describes driven section (teeth at the top). Each character in a string represents one section unit — 1 for a cavity and 2 for a tooth. The sections can not be flipped or rotated. Each string is non-empty and its length does not exceed 100.
Output
For each test case, write to the output a line containing a single integer number — the minimal length of the stripe required to cut off given sections.
Sample Input
2112112112 2212112 12121212 21212121 2211221122 21212
Sample Output
10 8 15
题意:
给出两个串,每列高度只能为1或者2,需要将它们放入一个高度为3的容器,求最短容器的长度。
思路:
串匹配问题。类似暴力的BF算法。
先固定a串移动b串进行匹配,再固定b串移动a串进行匹配。每一种方式的结果是 max(被固定住的串的长度加上移动串与固定串重合位置的和 ,被固定住的串的长度)。通过比较两种匹配方式得到最后的结果,取小的值作为最短容器长度的解。
1 #include<bits/stdc++.h> 2 #define maxn 10010 3 using namespace std; 4 char a[105],b[105]; 5 int a1[300],b1[300]; 6 7 int main() 8 { 9 while(~scanf("%s %s",a,b)) 10 { 11 int len=strlen(a); 12 int len1=strlen(b); 13 int i,j; 14 memset(a1,0,sizeof a1); 15 memset(b1,0,sizeof b1); 16 for(i=0;i<len;i++) 17 a1[i]=a[i]-'0'; 18 for(i=0;i<len1;i++) 19 b1[i]=b[i]-'0'; 20 for(i=0;i<len;i++) 21 {for(j=0;j<len1;j++) 22 { 23 if(a1[i+j]+b1[j]>3)break; 24 } 25 if(j==len1)break; 26 } 27 int ans1=max(len,i+len1); 28 for(i=0;i<len1;i++) 29 { 30 for(j=0;j<len;j++) 31 { 32 if(b1[i+j]+a1[j]>3)break; 33 } 34 if(j==len)break; 35 } 36 int ans2=max(i+len,len1); 37 printf("%d\n",min(ans1,ans2)); 38 } 39 return 0; 40 }
后来想到,能不能把两个存放高度的int数组去掉,直接if(b[i+j]-'0'+a[j]-'0'>3)break;然而这样一写就WA了,后来想到,因为b[],a[]的范围开的太小了,可能i+j>len1 or i+j>len;每个字符串最长是100,那么我们一定开大小在200以上。改完数组的大小,还是WA了,原因是先前输入的b[]比如长度是50,那么[0,49]是有字符的,后面全部设为'\0'转换成int大小为0,当(i+j)>len1,b[i+j]=0,b[i+j]-'0'不是我们预想要得到的结果了。
怎么办?我们可以在匹配串的时候增加一个条件if(i+j>len1)b[i+j]='0';,也可以,在外部增加两个循环
for(int i=len;i<300;i++)a[i]='0';
for(int i=len1;i<300;i++)b[i]='0';(建议还是第一种方法,复杂度低一点,虽然都能AC)
1 #include<bits/stdc++.h> 2 #define maxn 10010 3 using namespace std; 4 char a[220],b[220]; 5 6 int main() 7 { 8 while(~scanf("%s %s",a,b)) 9 { 10 int len=strlen(a); 11 int len1=strlen(b); 12 int i,j; 13 //for(int i=len;i<300;i++)a[i]='0'; 14 //for(int i=len1;i<300;i++)b[i]='0'; 15 for(i=0;i<len;i++) 16 {for(j=0;j<len1;j++) 17 { 18 if(i+j>len)a[i+j]='0'; 19 if(a[i+j]-'0'+b[j]-'0'>3)break; 20 } 21 if(j==len1)break; 22 } 23 int ans1=max(len,i+len1); 24 for(i=0;i<len1;i++) 25 { 26 for(j=0;j<len;j++) 27 { 28 if(i+j>len1)b[i+j]='0'; 29 if(b[i+j]-'0'+a[j]-'0'>3)break; 30 } 31 if(j==len)break; 32 } 33 int ans2=max(i+len,len1); 34 printf("%d\n",min(ans1,ans2)); 35 } 36 return 0; 37 }