USACO历年白银组真题解析 | 2023年1月Find and Replace

学习C++从娃娃抓起!记录下USACO(美国信息学奥赛)备考白银组别比赛学习过程中的题目,记录每一个瞬间。

附上汇总贴:USACO历年白银组真题解析 | 汇总-CSDN博客


【题目描述】

Bessie 正在使用世界上最先进最伟大的文本编辑器:miV!她想将一个仅由大写和小写英文字母组成的字符串转换为一个新的字符串。每一次操作,miV 可以将字符串中所有的字母 c1 替换成另一种字母 c2。例:对于字符串aAbBa, 如果将其中的 a 替换成 B, 那么字符串会变为BAbBB。

Bessie 非常地忙碌, 所以对于给出的 T(1≤T≤10) 组测试数据, 请输出她至少需要多少次操作才能把原字符串转换为新字符串。

【输入】

第一行是一个整数 T, 表示测试数据的数量。

接下来有 T 对长度相等的字符串。字符串中所有的字符都是大写或小写的字母。字符串的长度不会超过 105105。

【输出】

对于每组测试数据,输出转换字符串需要的最小操作数。

如果这不可能做到,输出 −1。

【输入样例】

4
abc
abc
BBC
ABC
abc
bbc
ABCD
BACD

【输出样例】

0
-1
1
3

【代码详解】

USACO历年白银组真题解析 | 2023年1月Find and Replace_第1张图片

#include 
using namespace std;
const int maxN = 55;
int to[maxN], inDeg[maxN], start[maxN];
int ch2i(char x)  // 将字符串转为数字,便于作为数组下标存储数据
{
    return isupper(x) ? x-'A'+1 : x-'a'+27;  // 如果是大写A-Z,就是1-26,如果是小写a-z,就是27-52
}
int main()
{
    int T;
    cin >> T;  // 输入T
    while (T--) {  // 遍历T组数据
        memset(to, 0, sizeof(to));  // 每次清空to、inDeg、start数组
        memset(inDeg, 0, sizeof(to));
        memset(start, 0, sizeof(to));

        string s, t;
        cin >> s >> t;  // 输入源字符串s和目标字符串t
        set st;  // 定义集合(无重复元素)
        bool ok = true, same = true;  // 定义标记位标记是否有同一个源字符指向不同的目标字符、是否所有位置都相同
        int len = s.size();  // 获取字符串长度
        for (int i=0; i 1) {  // 如B就有多个入点
                        multiIn = true;  // multiIn就修改为true
                    }
                    v = to[v];  // 遍历环上的所有点
                } while (v!=u);  // 一直到v与u相同退出循环
                if (!multiIn) {  // 如果环上的点没有多个入度
                    ans++;  // 答案要自增1
                }
            }
        }
        cout << ans << endl;  // 输出方案数
    }
    return 0;
}

【运行结果】

4
abc
abc
0
BBC
ABC
-1
abc
bbc
1
ABCD
BACD 
3

你可能感兴趣的:(算法)