UVa - 1588: 简单的迭代器运用

题目描述

有两个长度分别为 n1n2 的长条,长条每格高度分别为 h2h,呈齿状上下咬合在一起。长条不能调换上下顺序,不能前后翻转。现将两长条装入高度为 3h 的容器内,求容器所需的最小长度。

  • 输入

输入包含多组数据,每组第一行是表示下方长条的字符串,第二行是表示上方长条的字符串。字符串只含数字 1 和 2 ,表示每格高度;字符串长度不超过 100。输入到文件末尾结束。

  • 输出

对每组数据,输出一行表示容器最小长度的整数。

  • 样例输入
211112
2222
  • 样例输出
6

简单分析

用字符串存储输入数据。遍历所有组合情况,计算符合题设情形情况的总长度并维护其最小值。

  • 输入输出框架
#include
#include
int min_fix_length(std::string &a, std::string &b);
int main() {
    std::ios::sync_with_stdio(false);
    std::string a, b; while (std::cin >> a >> b) {
        std::cout << min_fix_length(a, b) << std::endl;
    }
    return 0;
}
  • std::ios::sync_with_stdio(false)取消iostream与stdio的同步,从而加快读写速度。

算法分析

容易得知一共有 n1 + n2 种组合。可以遍历字符串 a 和 b 上的每一个位置,从位置开始与另一字符串逐一比对,直到任一到达字符串末尾。

使用迭代器遍历。可以使用下标,但使用下标遍历并不会获得更低的开销。代码如下:

#include
#include
int min_fix_length(std::string &a, std::string &b) {
    auto res_len{a.size() + b.size()};
    for (auto it{a.begin()}; it != a.end(); ++it) {
        auto a_i{it}, b_i{b.begin()};
        bool is_fix{true}; while (a_i != a.end() && b_i != b.end()) {
            if (*a_i++ - '0' + *b_i++ - '0' > 3) {is_fix = false; break;}
        }
        if (is_fix) {
            auto crt_len{std::max(it - a.begin() + b.size(), a.size())};
            if (res_len > crt_len) res_len = crt_len;
        }
    }
    for (auto it{b.begin()}; it != b.end(); ++it) {
        auto a_i{a.begin()}, b_i{it};
        bool is_fix{true}; while (a_i != a.end() && b_i != b.end()) {
            if (*a_i++ - '0' + *b_i++ - '0' > 3) {is_fix = false; break;}
        }
        if (is_fix) {
            auto crt_len{std::max(it - b.begin() + a.size(), b.size())};
            if (res_len > crt_len) res_len = crt_len;
        }
    }
    return res_len;
}
  • *a_i++ - '0' + *b_i++ - '0' > 3中,运算优先级顺序是 ++ > * > +/- > >

  • std::max()返回“上层”长度和“下层”长度中的较大值,即当前组合情形的总长度。

注意 a 和 b 左对齐的情况处理了两次,同时没有处理 a 和 b 并排放置的情况。但这并不影响算法的正确性。

算法复杂度

  • 空间复杂度

迭代器没有额外空间开销,空间复杂度 O(n1 + n2) 来自输入数据的存储。

  • 时间复杂度

算法的时间复杂度表达式为 Sum[0 < i < n1] Min(i, n2)+ Sum[0 < i < n2] Min(i,n1) ,结果约等于 O(n1 * n2)

AC 代码

#include
#include
#include
int main() {
    std::ios::sync_with_stdio(false);
    std::string a, b; while (std::cin >> a >> b) {
        auto ans{a.size() + b.size()};
        for (auto it{a.begin()}; it != a.end(); ++it) {
            auto a_i{it}, b_i{b.begin()};
            bool is_fix{true}; while (a_i != a.end() && b_i != b.end()) {
                if (*a_i++ - '0' + *b_i++ - '0' > 3) {is_fix = false; break;}
            }
            if (is_fix) {
                auto crt{std::max(it - a.begin() + b.size(), a.size())};
                if (ans > crt) ans = crt;
            }
        }
        for (auto it{b.begin()}; it != b.end(); ++it) {
            auto b_i{it}, a_i{a.begin()};
            bool is_fix{true}; while (a_i != a.end() && b_i != b.end()) {
                if (*a_i++ - '0' + *b_i++ - '0' > 3) {is_fix = false; break;}
            }
            if (is_fix) {
                auto crt{std::max(it - b.begin() + a.size(), b.size())};
                if (ans > crt) ans = crt;
            }
        }
        std::cout << ans << std::endl;
    }
    return 0;
}

你可能感兴趣的:(UVa - 1588: 简单的迭代器运用)