一道结论题,代码相当的短。
我们先来考虑会拼出重复的情况:
那必定是第一个字符串里有一个 $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; }
标签:YACS,++,题解,s1,乙组,long,int,s2,字符串 From: https://www.cnblogs.com/Xy-top/p/17046004.html