Codeforces 825 D Suitable Replacement

题目地址:http://codeforces.com/contest/825/problem/D
题意:给你两个字符串,第一个字符串里会有‘?’,‘?’可以替换任意为字母,要求你把字符串中的‘?’全部换成字母,要能与第二个字符串有最大匹配数,然后他并不要求是匹配的是子串,只要是字母个数和第二个字符串字母个数相同就算是匹配的(这个要理解,比如第一个字符串是abba,第二个是ab,按他的规则最大匹配数是2),匹配过一次就不能再利用了。(字符串可以调换顺序,就简单很多了,一开始我还以为不能调换顺序)
思路:因为可以调换顺序所以直接记录需要多少某个字母就好了,我的代码是模拟过程,先把‘?’的个数记录下来,再把可以构成第二个字符串的个数全部在第一个字符串中去掉,然后每次判断构成第二个字符串需要多少字符,一次次的减去‘?’个数,直到所有‘?’个数全部用完。但是我觉得正确写法应该是二分枚举最后拥有的第二个字符串个数,有兴趣的可以试下看

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <algorithm>
#define LL long long 
#define N 1010
#define M 50010
#define inf 0x3f3f3f3f
using namespace std;
const LL mod = 1e9 + 7;
const double eps = 1e-9;
map<char, LL> map1, map2, used;
int main() {
    cin.sync_with_stdio(false);
    string a, b;
    while (cin >> a >> b) {
        map1.clear();
        map2.clear();
        used.clear();
        LL ans = 0;
        LL cnt = 0;
        for (int i = 0; i < a.length(); i++) {
            if (a[i] == '?') {
                ans++;
            }
            else{
                if (map1.find(a[i]) == map1.end()) {
                    map1[a[i]] = 0;
                }
                map1[a[i]]++;
            }
        }
        for (int i = 0; i < b.length(); i++) {
            cnt++; 
            if (map2.find(b[i]) == map2.end()) {
                map2[b[i]] = 0;
            }
            map2[b[i]]++;
        }
        LL flag = inf;
        for (map<char, LL>::iterator it = map2.begin(); it != map2.end(); it++) {
            flag = min(map1[it->first] / it->second, flag);
        }
        for (map<char, LL>::iterator it = map2.begin(); it != map2.end(); it++) {
            map1[it->first] -= flag*it->second;
        }
        while (ans>0) {
            for (map<char, LL>::iterator it = map2.begin(); it != map2.end(); it++) {
                if (ans < 0) {
                    break;
                }
                if (map1[it->first] >= it->second) {
                    map1[it->first] -= it->second;
                }
                else {
                    if (used.find(it->first) == used.end()) {
                        used[it->first] = 0;
                    }
                    int kk = min(ans, it->second - map1[it->first]);
                    used[it->first] += kk;
                    map1[it->first] = 0;
                    ans -= kk;
                }
            }
        }
        int i = 0;
        for (map<char, LL>::iterator iter = used.begin(); iter != used.end(); iter++) {
            for (int j = 0; j < iter->second; j++) {
                while (a[i] != '?') {
                    cout << a[i];
                    i++;
                    if (i == a.length()) {
                        return 0;
                    }
                }
                cout << iter->first;
                i++;
            }
        }
        for (; i < a.length(); i++) {
            cout << a[i];
        }
        cout << endl;
    }
    return 0;
}

版权声明:本文为xjh_shin原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。