习题3-11 UVA1588 Kickdown(44行AC代码)

紫书刷题进行中,题解系列点这里

习题3-11 UVA1588 Kickdown(44行AC代码)

思路分析

给定两个数字串,仅由1、2组成,当相应位置不同时为2时,说明两个位置匹配,这题本质就是找最长匹配长度max,两个数字串长度总和-max即为结果。

假设数字串a,b,且a长度小于b,且固定b,向右移动a,考虑三种位置情况:

  • a在b左侧
  • a在b内部
  • a在b右侧

简单遍历,每次取最小即可

注意点

  • a在b的左侧容易遗忘

  • 题目明确要求无需考虑反转,若反转,有些结果会变小,比如12,12会变成2,正确应是3

  • 可通过增加线段起点,统一3中情况,优化代码,参考博文

AC代码(C++11,双串匹配)

#include<bits/stdc++.h>
using namespace std;
string a, b;
int getMin(string a, string b) { // 获取a和b最小的组合长度
    if (a.size() > b.size()) swap(a,b); // a为短者
    int MIN = a.size() + b.size();
    for (int i = a.size(); i > 0; i --) { // a的长度;a在b左侧
        int j;
        for (j = 0; j < i; j ++) {
            if (a[a.size()-i+j] == '2' && b[j] == '2') break;
        }
        if (j == i) { // 找到第一个符合
            MIN -= i;
            break;
        }
    }
    for (int i = 0; i <= b.size()-a.size(); i ++) { // b的起始位置;a包含于b
        int j;
        for (j = 0; j < a.size(); j ++) {
            if (a[j] == '2' && b[i+j] == '2') break;
        }
        if (j == a.size()) {
            MIN = b.size();
            break;
        }
    }
    for (int i = a.size()-1; i > 0; i --) { // a的长度;a在b右侧
        int j;
        for (j = 0; j < i; j ++) {
            if (a[j] == '2' && b[b.size()-i+j] == '2') break;
        }
        if (j == i) {
            MIN = min(MIN, (int)(a.size()+b.size()-i));
            break;
        }
    }
    return MIN;
}
int main() {
    while(cin >>a >>b) {
        printf("%d\n", getMin(a,b));
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值