#P1892. 第2题-积木
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 149
            Accepted: 28
            Difficulty: 5
            
          
          
          
                       所属公司 : 
                              京东
                                
            
                        
              时间 :2024年8月17日
                              
                      
          
 
- 
                        算法标签>模拟          
 
第2题-积木
思路:模拟
积木每个单位的高度为1或2,拼接后不能超过3,所以耦合需要1和2的组合,即不能同时为2。
由于数据较小,因此模拟即可。判断串s的一个后缀是否能够与t的前缀耦合,即判断这两部分是否同时出现了2。
因此时间复杂度为O(N2)
代码
Java
import java.util.Scanner;
public class Main {
    static Scanner sc = new Scanner(System.in);
    public static void main(String[] args) {
        // 读取两个整数 a 和 b
        int a = sc.nextInt();
        int b = sc.nextInt();
        
        // 读取两个字符串 s 和 t
        String s = sc.next();
        String t = sc.next();
        // 初始答案为 a 和 b 的和
        int ans = a + b;
        // 检查 s 的后缀和 t 的重叠部分
        for (int i = 0; i < s.length(); i++) {
            if (isValidOverlap(s.substring(i), t)) {
                int overlapLength = i + Math.max(s.length() - i, t.length());
                ans = Math.min(ans, overlapLength);
            }
        }
        // 检查 t 的后缀和 s 的重叠部分
        for (int i = 0; i < t.length(); i++) {
            if (isValidOverlap(t.substring(i), s)) {
                int overlapLength = i + Math.max(t.length() - i, s.length());
                ans = Math.min(ans, overlapLength);
            }
        }
        // 输出最小的重叠长度
        System.out.println(ans);
    }
    // 判断两个字符串的当前部分是否可以重叠
    private static boolean isValidOverlap(String s, String t) {
        int minLength = Math.min(s.length(), t.length());
        for (int i = 0; i < minLength; i++) {
            if (s.charAt(i) == '2' && t.charAt(i) == '2') {
                return false; // 如果两个字符串在同一位置上都为 '2',则不能重叠
            }
        }
        return true; // 如果没有冲突,则返回 true
    }
}
C++
#include <bits/stdc++.h>
using namespace std;
int n, m;
vector<int> first_bricks;
vector<int> second_bricks;
int main() {
    string s1;
    string s2;
    cin >> n >> m;
    cin >> s1 >> s2;
    first_bricks.resize(n);
    second_bricks.resize(m);
    for (int i = 0; i < n; i++) {
        first_bricks[i] = s1[i] - '0';
    }
    for (int i = 0; i < m; i++) {
        second_bricks[i] = s2[i] - '0';
    }
    int ans = n + m;
    vector<int> sum(2 * n + m, 0);
    int second_begin_idx = n;
    int second_end_idx = n + m;
    for (int i = 0; i < n + m; i++) {
        int first_begin_idx = i;
        int first_end_idx = i + n;
        int flag = 0;
        for (int j = 0; j < 2 * n + m; j++) {
            int top_v = (j >= first_begin_idx && j <= first_end_idx) ? first_bricks[j - first_begin_idx] : 0;
            int bottom_v = (j >= second_begin_idx && j <= second_end_idx) ? second_bricks[j - second_begin_idx] : 0;
            if (top_v + bottom_v == 4) {
                flag = 1;
                break;
            }
        }
        if (flag == 0) {
            ans = min(ans, max(first_end_idx, second_end_idx) - min(first_begin_idx, second_begin_idx));
        }
    }
    cout << ans;
    return 0;
}
Python
temp_in = input().split()
n, m = int(temp_in[0]), int(temp_in[1])
s_n = input().split()[0]
s_m = input().split()[0]
def calc(n, m, s_n, s_m):
    result = m+n
    m_2 = [idx for idx, c in enumerate(s_m) if c == '2']
    for i in range(2):
        # 积木n 正向/反向 两种情况
        # if i == 1:
        #     s_n = s_n[::-1]
        n_2 = [idx for idx, c in enumerate(s_n) if c == '2']
        
        # 构造一个m+n+1的空间用来存储本次可以成功拼接的情况
        # 字符串n不动,只移动m,记录m的第一个字符的位置
        record = [ _ for _ in range(m+n+1)]
        for m_i in m_2:
            for n_i in n_2:
                temp_idx = m + n_i - m_i
                record[temp_idx] = -1
        # print(record)
        # 计算每种拼接情况的总长度
        for idx in record:
            if idx != -1:
                temp_ans = m+n
                if idx < m:
                    temp_ans = max(m, m-idx+n)
                else:
                    temp_ans = max(n, idx)
                if temp_ans < result:
                    result = temp_ans    
                    # print(idx, temp_ans)       
        
    return result
print(calc(n, m, s_n, s_m))
        题目描述
NN有一种锯齿状的积木,这种积木比较长,但是每个单位长度的高度是相等的高度为 1 或者 2。
现在NN拿出了两块长度分别为n和 m 的积木,她现在想把这两块积木拼接在起,即使中间有空隙也没有关系。
但是拼接后的积木的高度要不超过 3,请你帮助NN计算在满足这个前提下拼接后的积木的长度最短可以是多少。
注:本题正解应当考虑积木可以翻转,但是考场上不翻转积木反而AC了,所以本题应当额外加上“不能够翻转积木”的条件
输入描述
第一行给出两个正整数 n,m,代表第一块和第二块积木的长度
第二行给出 n 个数字代表第一块积木每个单位的高度
第三行给出 m 个数字代表第二块积木每个单位的高度 1≤n,m≤1000
输出描述
一个整数,表示拼接后的积木的最短长度
样例
输入
7 10
2212112
2112112112
输出
10
输入
3 2
222
22
输出
5