寻找最少的切换次数,实际上只要让最晚出现的服务器与代理服务器重合时对应的IP地址作为此前所有服务器的代理即可。

#include <bits/stdc++.h>
#define _CRT_SECURE_NO_DEPRECATE

int main() {
    int n, m;
    std::vector<std::string> agentIP;
    std::vector<std::string> serverIP;
    int ans = -1;
    std::string IP;
    while (std::cin >> n) {
        for (int i = 0; i < n; i++) {
            std::cin >> IP;
            agentIP.push_back(IP);
        }
        std::cin >> m;
        for (int i = 0; i < m; i++) {
            std::cin >> IP;
            serverIP.push_back(IP);
        }
        ans = 0;
        std::vector<bool> markedAgent(n);
        for (int i = 0; i < n; i++) {
            markedAgent[i] = false;
        }
        for (int i = 0; i < m; i++) {
            if (ans == -1) break;
            for (int j = 0; j < n; j++) {
                if (serverIP[i] == agentIP[j]) {
                    // 访问的服务器就是代理服务器
                    if (n == 1) {
                        // 备选代理服务器没有其他选项,对应无法规划出合适的方案
                        ans = -1;
                        break;
                    }

                    /* Greedy
                    依次访问服务器IP,如遇到代理服务器则标记。
                    直到遇到一个代理服务器并标记后所有的代理服务器均已被标记,
                    那么这时可以理解为此前所有服务器(不含当前)访问均为这个代理服务器。
                    此时切换代理,并清除这个代理服务器之外的所有标记,如此反复。
                    */

                    markedAgent[j] = true; // 标记代理服务器
                    bool allAgentMarked = true;
                    // 判断是否所有代理服务器均被标记过
                    for (int k = 0; k < n; k++) {
                        if (markedAgent[k] == false) {
                            allAgentMarked = false;
                            break;
                        }
                    }
                    if (!allAgentMarked) break;
                    // 此时如果还在循环内则一定是代理服务器均已被标记,对应此前所有的访问全都由代理服务器“j”进行
                    ans++; // 切换
                    for (int k = 0; k < n; k++) {
                        markedAgent[k] = false; // 重置标记
                    }
                    markedAgent[j] = true; // 将切换前的代理服务器标记
                    break;
                }
            }
        }
        std::cout << ans << std::endl;
    }
    return 0;
}