1.题目描述:点击打开链接
2.解题思路:本题要求找一个尽量小的长度,使得能够容纳下两个不同的装置。还是考虑暴力搜索:假设两个装置分别为a,b,长度分别为n1,n2,那么固定b(b的起始位置固定到位置n1),从左往右枚举a的起始位置,看能否和b进行匹配。如果可以,更新最小的长度。输出即可。
另外,也可以从对称性的角度考虑。由于固定装置是相对的,因此考虑固定b和固定a两者的最小值即可。
3.代码:
(只固定装置b)
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; #define N 100+10 int a[N], b[N]; int c[3 * N]; int n1, n2; int ans; bool match(int pos) { memset(c, 0, sizeof(c)); for (int i = n1; i < n1 + n2; i++)//固定装置b c[i] = b[i - n1]; for (int i = pos; i < pos + n1; i++) { if (!c[i])c[i] = a[i-pos]; else if (c[i] + a[i-pos]>3)return false; else c[i] += a[i-pos]; } return true; } int getlen(int*c) { int cnt = 0; for (int i = 0; i < 2 * n1 + n2;i++) if (c[i])cnt++; return cnt; } int main() { //freopen("t.txt", "r", stdin); string s1, s2; while (cin>>s1) { cin >> s2; memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); n1 = s1.length(); n2 = s2.length(); for (int i = 0; i < n1; i++) a[i] = s1[i] - '0'; for (int i = 0; i < n2; i++) b[i] = s2[i] - '0'; int _min = 500; for (int i = 0; i < n1 + n2;i++) if (match(i)) _min = min(_min, getlen(c)); cout << _min << endl; } return 0; }
(利用对称性,考虑固定a和固定b的较小者)
#include <iostream> #include <algorithm> #include <stdio.h> #include <string.h> using namespace std; bool test(int k,char s1[],char s2[]){ for(int i = 0; s1[k+i] && s2[i]; i++)//这里的循环终止条件很值得学习! if(s1[k+i]+s2[i]-2*'0' > 3)return false; return true; } int fun(char s1[],char s2[]){ int k = 0; while(!test(k,s1,s2))k++;//s1固定,向右移动s2 return max(strlen(s1),strlen(s2)+k); } int main(){ char bottom[105],top[105]; while(scanf("%s%s",bottom,top) != EOF)//对称性 cout<<min(fun(bottom,top),fun(top,bottom))<<endl; return 0; }