#include <bits/stdc++.h>
using namespace std;
int main() {
// 包含全部需要珠子 剩余 或缺少
// 跟旧键盘的思路类似 一个预定的输入 一实际输出
map<char, int> store, red;
string s, r;
// 读取摊主和小红的字符串
getline(cin, s);
getline(cin, r);
// 用map统计每个字符的个数
for(int i = 0; i < s.size(); i++)
store[s[i]]++;
for(int i = 0; i < r.size(); i++)
red[r[i]]++;
// 统计多出或少于的(字符)数
int more = 0, lose = 0;
for(auto s: store){
// 区分情况
// 遍历每一个字符 供给多于需求 (等于 算不算都一样 都是0
if(s.second > red[s.first])
more += s.second - red[s.first];
// 找得到 但少于需求
else
lose += red[s.first] - s.second;
// 擦除遍历过的需求的字符
red.erase(s.first);
}
// 遍历剩余字符 这部分必然是缺少的字符
for(auto r: red)
lose += r.second;
if(lose > 0)
cout << "No " << lose;
else
cout << "Yes " << more;
}
开始的时候以为跟前面旧键盘的思路差不多。但是写到后面的情况发现不太对。相似的处理仅限于供给能够满足需求的时候,这时候两个集合的元素 供给 ≥ 需求。
这个情况可以类比当时旧键盘题目的时候,当输入经过处理使得部分缺失而得到实际输出,也是 输入 ≥ 输出。
但这里如果供给不满足需求,意味着两个集合的元素有一部分是没有交叉的。比如供给有 1 2 3 需求是 2 3 4,那么这时候 4 就游离在两个集合的交集之外了。这部分就是跟旧键盘题目不一样的地方。
所以需要考虑对交集以外的部分进行处理,就是循环处理两次,一次解决交集部分,另一次解决交集以外。
参考别人的思路。可以将需求和供给的元素个数放在同一个 map 容器里面,当读取供给字符的时候 ++, 需求字符的时候 -- 。最后将正负不同的部分分别求和即可。
我们原本是先读取两个不同部分各自的元素个数,然后运算再统计。参考的思路里面,可以看到最终结果都是要运算统计的,所以就省去了储存的步骤,直接在读取字符串时就运算。