题意:
给两个长条,长条上一列一列顺序排列,且每列高度只为1或2,将这两个长条‘嵌套“,每列总高度不得超过3,问最终形成的新长条最短有多长?
思路:
可以将一个长条s1看成固定,另外一个s2依次后移寻找能否嵌套,如果从头至尾扫描s2都符合高度不超过三,那就成功了,否则将s2的起始扫描位置后移。具体可见代码。
注意:
题目中有这么一句话!The sectionscan not be flipped or rotated.意思是这种长条不能被翻转或旋转。
那就只能从左向右移动,而且不能将长条逆置。这样的话,只需要扫描两次。一次以s1为基准,s2主动后移;一次以s2为基准,s1主动后移。
#include <stdio.h>
#include <string.h>
int a[250], b[250], i, j, lena, lenb, ans1, ans2, min;
char s1[110], s2[110];
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
while (scanf("%s%s", s1, s2)!=EOF)
{
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
lena = strlen(s1);
lenb = strlen(s2);
for (i = 0;i < lena;i++)
a[i] = s1[i] - '0';
for (i = 0;i < lenb;i++)
b[i] = s2[i] - '0';//转化成相应数字
for (i = 0;i < lena;i++)
{
for (j = 0;j < lenb;j++)
{
if ((a[i + j] + b[j])>3)//因为i+j的存在所以a、b数组要开大一倍
break;
}
if (j == lenb) break;//成功‘嵌套’
}
//printf("i=%d,j=%d\n", i, j);
ans1 = (((i + lenb)>lena) ? (i + lenb) : lena);
for (i = 0;i < lenb;i++)
{
for (j = 0;j < lena;j++)
{
if ((a[j] + b[j+i])>3)
break;
}
if (j == lena) break;//成功‘嵌套’
}
//printf("i=%d,j=%d\n", i, j);
ans2 = (((i + lena)>lenb) ? (i + lena) : lenb);
min = ans1 < ans2 ? ans1 : ans2;//取两种扫描中最小的
printf("%d\n", min);
}
return 0;
}
附上几组额外测试数据。
2222
21112(9)
222
21112(5)
21122
21122(7)
21122
21222(10)
2212112
2112112112(10)
12121212
21212121(8)
2211221122
21212(15)
1
2(1)
11
22(2)
2
2(2)