习题3-11 换低挡装置(Kickdown, ACM/ICPC NEERC 2006, UVa1588)
给出两个长度分别为n1,n2(n1,n2≤100)且每列高度只为1或2的长条。需要将它们放
入一个高度为3的容器(如图3-8所示),问能够容纳它们的最短容器长度。 这里写图片描述
Sample Input
2112112112
2212112
12121212
21212121
2211221122
21212
Sample Output
10
8
15

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=830&problem=4463&mosmsg=Submission+received+with+ID+20560401
用两个字符串数组分别存这两个块,一块作为不动的,另一块在其上移动,判断当前移动到的位置是不是和下块契合(用循环依次比较各个位置),若不是则继续移动到下一位。
需要注意的是,最短的契合方案有可能你漏想了,下面一共是三种可能的情况。所以我用一个函数来将两个块换了位置后又移动了一次。

//三种情况:bbbbb aa (|a|:ab重叠
//1.短块在长块里(bb|aa|b)
//2.短块头在长块里(外),短块尾巴超出长块尾(bbbb|a|a)
//3.长块头在短块尾(外),长块尾巴超出短块尾(a|a|bbbb)
//不要忘记第三种情况,有时最短空间就是出自3
#include<iostream>
#include<cstring>
using namespace std;
const int N = 100;
//int kick1[N+5],kick2[N+5];
int kickdown(string k1,string k2)//定k1,移k2
{
        //cout<<k1.size()<<"  "<<k2.size()<<endl;
    for(int i=0;i<k1.size();i++)
    {
        int ii=i,j=0;//i就是大小块契合的那一位
        //cout<<ii<<" "<<j<<endl;
        while((k1[ii]-'0'+k2[j]-'0')<=3&&(j<k2.size()&&ii<k1.size()))//若当前位不匹配则进行for到下一位
        {
            //cout<<"k1 ii "<<ii<<"  "<<k1[ii]<<" | k2 j"<<j<<"  "<<k2[j]<<endl;
            ii++;
            j++;
        }
        if(j==k2.size()||ii==k1.size())//若是寿终正寝(即循环到块尾了)
        {
            //cout<<j<<"  i "<<i<<endl;
            return (i+k2.size())>=k1.size()?(i+k2.size()):k1.size();
            //若i+k2.size()比k1(长块)的长度还短,那么所需长度就直接是k1长度了
            /*下面是通俗代码*/
            //space=i+k2.size();
            //if(space<k1.size())
            //    space=k1.size();
            //break;
        }
    }
    return k1.size()+k2.size();//若没有契合处,只能接到后面了
}

int main()
{
    string k1,k2;//咱们要k1>k2
    while(cin>>k1>>k2)
    {
        int space1=0,space2=0;
        space1=kickdown(k1,k2);
        space2=kickdown(k2,k1);
        //cout<<"s1   "<<space1<<"  s2 "<<space2<<endl;
        cout<<(space1<space2?space1:space2)<<endl;
    }
    return 0;
}
//AC at 2018/1/2

一开始我被题目中的例子所蒙蔽,想的是固定长的块,移动短的块,最后算下来和网友给的样例比总是有一些要大上几个数。那人一口气给了500+对数十上百个元素的12字符串,想用cout断点的方式看出一些端倪是十分困难的。这道题花了两天吧,太糟。