1 条题解

  • 0
    @ 2026-4-14 20:30:49

    A. 棘手的模板 题解


    1. 题目理解

    我们有三个长度为 nn 的字符串 aabbcc,均由小写字母组成。我们需要构造一个模板 tt,长度也为 nn,每个位置可以是小写字母或大写字母,满足:

    • 对于 aabb:所有位置都必须与模板匹配;
    • 对于 cc:至少有一个位置与模板不匹配。

    匹配规则(对于每个位置 ii):

    • tit_i 是小写,则字符串在该位置的字母必须等于 tit_i
    • tit_i 是大写,则字符串在该位置的字母必须不等于 tit_i 对应的小写字母。

    题目要求判断是否存在这样的模板。


    2. 关键观察

    对于位置 ii,我们分析模板在该位置的字符 tit_i 的两种可能:

    情况 1:tit_i 为小写字母(假设为 xx

    此时匹配条件为:

    • ai=xa_i = x
    • bi=xb_i = x
    • cixc_i \neq x (我们希望 cc 不匹配)

    因此,为了让 aabb 同时匹配,必须有 ai=bia_i = b_i;同时,为了让 cc 不匹配,必须有 ciaic_i \neq a_i

    情况 2:tit_i 为大写字母(假设为 XX,对应小写为 xx

    此时匹配条件为:

    • aixa_i \neq x
    • bixb_i \neq x
    • ci=xc_i = x (希望 cc 不匹配)

    注意,要使 cc 不匹配,必须 ci=xc_i = x,即 cic_i 恰好等于该大写字母的小写形式。而 aabb 要匹配,必须它们都不等于 xx。因此,只要 aicia_i \neq c_ibicib_i \neq c_i,我们就可以选择 tit_i 为对应 cic_i 的大写字母,使得 aabb 匹配(因为它们不等于 cic_i),而 cc 不匹配(因为 cic_i 等于该大写字母的小写形式)。


    3. 存在性条件

    由上述分析可知,只要存在某个位置 ii 满足 aicia_i \neq c_ibicib_i \neq c_i,我们就可以在这个位置放置一个大写字母(即 cic_i 的大写形式),使得 aabb 匹配,而 cc 不匹配。对于其他位置,我们可以随意设置模板使得 aabb 匹配(例如直接使用 aia_i 的小写形式,此时由于 ai=bia_i = b_i 则它们匹配,而 cc 在该位置可能匹配也可能不匹配,但只要有一个位置不匹配,整体 cc 就不匹配)。

    如果对于所有位置 ii,都不满足 aicia_i \neq c_ibicib_i \neq c_i,即对于每个位置,要么 ai=cia_i = c_i,要么 bi=cib_i = c_i(或两者都等于),那么无论我们如何选择模板,都无法让 cc 不匹配的同时保证 aabb 都匹配。因为:

    • 若选择小写字母,要求 ai=bi=tia_i = b_i = t_i,但此时若 ci=aic_i = a_icc 也会匹配,若 ciaic_i \neq a_i 则要求 ai=bicia_i = b_i \neq c_i,这又回到了 aicia_i \neq c_ibicib_i \neq c_i 的条件。
    • 若选择大写字母,要求 aicia_i \neq c_ibicib_i \neq c_i,这正是我们需要的条件。

    因此,当且仅当存在至少一个位置 ii 满足 aicia_i \neq c_ibicib_i \neq c_i 时,答案才为 YES,否则为 NO

    标程正是基于此判断。


    4. 算法步骤

    对于每个测试用例:

    1. 读入 nn 和三个字符串 aabbcc
    2. 遍历 i=0i = 0n1n-1
      • 如果 aicia_i \neq c_ibicib_i \neq c_i,标记找到可行位置,终止遍历。
    3. 若找到可行位置,输出 "YES";否则输出 "NO"

    时间复杂度:O(n)O(n) 每个测试用例。总复杂度 O(n)O(\sum n),由于 n20n \le 20,完全足够。


    5. C++ 代码

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        
        int t;
        cin >> t;
        while (t--) {
            int n;
            cin >> n;
            string a, b, c;
            cin >> a >> b >> c;
            
            bool found = false;
            for (int i = 0; i < n; ++i) {
                if (a[i] != c[i] && b[i] != c[i]) {
                    found = true;
                    break; // 找到一个即可
                }
            }
            cout << (found ? "YES" : "NO") << '\n';
        }
        return 0;
    }
    

    6. 总结

    本题巧妙地将模板匹配条件转化为简单的字符不等关系判断。关键在于意识到:要使 cc 不匹配,我们只需在一个位置上利用大写字母的“排斥”性质,而该位置必须满足 aabb 都与 cc 不同。该思路简洁且易于实现。

    • 1

    信息

    ID
    6518
    时间
    1000ms
    内存
    256MiB
    难度
    1
    标签
    递交数
    1
    已通过
    1
    上传者