YACS 2022年12月月赛 乙组 T1 拼接单词 题解

题目链接

一道结论题,代码相当的短。
我们先来考虑会拼出重复的情况:
那必定是第一个字符串里有一个 $a$(其他的也行),第二个也有一个 $a$。

那么我们就可以选择拿第一个字符串 $a$ 前面的和第二个字符串 $a$ 后面拼。
至于两个 $a$,选其中一个就可以构造出两个一样的了。

需要注意的是, 如果第一个字符串的 $a$ 正好在第一位,或者第二个字符串的 $a$ 在最后一个就没有办法构造喽,所以我们忽略掉这两种构造情况。、

接着拓展到一般情况:第一个字符串中有 $s1$ 个 $a$,第二个中有 $s2$ 个 $a$。

那么一共可以构造出 $(s1 +1)\times (s2+1)$ 个单词。(前面选 $0-s1$ 个 $a$ 接后面选 $0-s2$ 个 $a$)

其中不重复的有多少呢?我们发现最少可以选 $0$ 个 $a$,最多可以选择 $s1 + s2$ 个 $a$。

不重复的一共有 $s1 + s2 + 1$ 个,重复的就有 $(s1 + 1)\times (s2 +1) - s1 - s2 - 1 = s1\times s2$ 个。

最后用所有的方案数减去重复的方案数就可以了。

注意开 $longlong$,代码相当的短,不压行只有 $13$ 行,可以和上升序列一决高下。

#include <iostream>
using namespace std;
string a, b;
long long ans, sum1, sum2;
long long b1[30], b2[30];
int main () {
    cin >> a >> b;
    for (int i = 1; i < a.size (); i ++) ++ b1[a[i] - 'a' + 1];
    for (int i = 0; i < b.size () - 1; i ++) ++ b2[b[i] - 'a' + 1];
    for (int i = 1; i <= 26; i ++) ans -= b1[i] * b2[i];
    cout << ans + a.size () * b.size ();
    return 0;
}

 

posted @ 2023-01-12 11:29  Xy_top  阅读(60)  评论(0)    收藏  举报