小猿有一台打字机,只能打出’A’、‘B’、'C’字符三种。某天小猿打了一段长度为N的字符串1,然后发现可以通过打字机的快捷操作来快速改写字符串。
已知一次快捷操作必须同时改写K个不同的位置的字符,且被改写的字符必须改写字符串,且被改写的字符必须改成打字机可以打出的其他字符。例如,K=2时,“AB"可以被改写成"CA”,也可以被改写为"BC",但不可以被改写为"AA"(必须恰好改写K个字符)或"EF"。
可以请问通过M次快捷操作,能有多少种将字符串1改写为目标字符串的方案?
输入描述: 第一行输入三个整数,N、M、K。
接下来两行输入原始字符串1和目标字符串2。
1<=N<=100 1<=M<=100
0<=K<=N
输出描述:
方案数
示例1
输入
3 2 3
AAA
CCC
输出
1
示例2
输入
2 2 2
AA
AA
输出
4
其实输出是方案数对1000000007取模的结果,不过这里没算;由于没有在实际试题上调试,实际AC率有待商榷,主要思路:把能在M次操作后变为目标字符的位和不能在M次操作后变为目标字符的位的分开;不能在M次操作后变为目标字符又分为两种情况:
(1).目标字符和源字符不同,意味着源字符串不可能在M次操作后变为目标字符,即方案数为0;
(2).目标字符和源字符相同,意味着这位是就是不能在M次操作后变为目标字符,在计算方案数时就可以不管这位了;
之后只要在能在M次操作变为目标字符这些位里计算方案数就好。
先同时遍历两个字符串,找出能在M次操作后变为目标字符的源字符位,并计算该位的方案数,把各个位的方案数push进一个vector里,之后对这个对这个vector计算方案数即可
主要思想是分而治之
假设这个vector有c1,c2,c3,c4,四个字符位的方案数,对应为k1,k2,k3,k4,现在假设同时操作2位,则总方案数位:
(k1+k2+k3)* k4
那么假如是同时操作3位,则总方案数为:
(k1+k2+k3) * k4*k5+(k1+k2) *k3 *k4 + k1 * k2 * k3
我们设从k1,k2,k3,k4,…,kn中抽K位数来操作的方案数的函数为:
F(k1,k2,k3,…kn;K)
假设已经确定抽了最后一个数kn,那么我们就只需要在剩下的k1,k2,k3,k4,…,kn-1个数里抽K-1位来操作
即 F(k1,k2,k3,…,kn-1;K-1) * kn
假设已经确定要抽最后倒数第二个数Kn-1,那么我们就只需要在剩下的k1,k2,k3,k4,…,kn-2个数里抽K-1位来操作
即F(k1,k2,k3,…,kn-2;K-1) * kn-1
假设已经确定要抽最后倒数第三个数Kn-2,那么我们就只需要在剩下的k1,k2,k3,k4,…,kn-3个数里抽K-1位来操作
即F(k1,k2,k3,…,kn-3;K-1) * kn-2
…
直到(k1,k2,k3,…kn-k)的数目不足抽K位来操作
所以F(k1,k2,k3,…kn;K) = F(k1,k2,k3,…,kn-1;K-1) * kn + F(k1,k2,k3,…,kn-2;K) * kn-1 + … +k1 * k2 * k3*…kn-k
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int tos2(char c1,char& c2,int m,int& count) {
if (m == 0) {
if (c1 == c2) {
count++;
return count;
}
else
return 0;
}
bool res;
switch (c1) {
case 'A':
tos2('B', c2, m - 1, count);
tos2('C',c2,m-1,count);
break;
case 'B':
tos2('A', c2, m - 1, count);
tos2('C', c2, m - 1, count);
break;
case 'C':
tos2('A', c2, m - 1, count);
tos2('B', c2, m - 1, count);
break;
}
return count;
}
int summr(vector<int>& vec, int len,int k) {
int sum = 0;
if (k == 0) return 1;
if (k == 1) {
for (int i = len-1; i >=0 ; i--) {
sum += vec[i];
}
return sum;
}
else {
for (int i = len - 1; i >= 0; i--) {
if (i + 1 < k) break;
sum += vec[i] * summr(vec, i, k - 1);
}
}
return sum;
}
int main() {
int n, m, k;
cin >> n >> m >> k;
string s1, s2;
cin >> s1;
cin >> s2;
vector<int> s1c;
for (int i = 0; i < s1.size(); i++) {
int count = 0;
if (tos2(s1[i], s2[i], m, count)) {
s1c.push_back(count);
}
else {
if (s1[i] != s2[i])
return 0;
}
}
int sum = 0;
int len = s1c.size();
sum = summr(s1c,len,k);
cout << sum << endl;
return 0;
}