题目链接:见这里
题意:每个队名有两种选择,然后第一个选择队名相同的那些队只能选第二种,让你安排队名,使得最后每个队名都不一样。
分析: 首先全都选成第一种队名,然后第一种队名相同的队,它们只能全都变成选第二种队名的了,这个时候如果第一种队名相同的那些队里面,变成第二种队名后有重复的,直接输出无解,这个时候先不管第一种队名,之后再处理第一种队名,看看第一种队名有没有和第二种队名重的,如果有重的话就让他变到第二种队名,以此法贪心就好。代码能力太差,debug好久好久。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1100;
int n;
string s1, s2;
string name1[maxn], name2[maxn]; //A, B
int pos[maxn]; //记录哪些需要变成第2种
map <string, vector <int> > mp1, mp2;
map <string, int> m1, m2;
map <string, bool> vis; //标记哪些第1种名字被处理

int main()
{
    //input
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> s1 >> s2;
        name1[i] = "", name2[i] = "";
        name1[i] += s1.substr(0, 3);
        name2[i] += s1.substr(0, 2);
        name2[i] += s2[0];
        mp1[name1[i]].push_back(i);
        m1[name1[i]]++;
    }
    //
    for(int i = 1; i <= n; i++){
        if(!vis[name1[i]]){
            int len = mp1[name1[i]].size();
            if(len > 1){
                for(int j = 0; j <= len - 1; j++){
                    m1[name1[i]]--;
                    int id = mp1[name1[i]][j];
                    pos[id] = 1;
                    m2[name2[id]]++;
                    if(m2[name2[id]] > 1){
                        puts("NO");
                        return 0;
                    }
                }
            }
            vis[name1[i]] = 1;
        }
    }
    //
    while(1){
        bool flag = 1;
        for(int i = 1; i <= n; i++){
            if(pos[i] == 0){
                if(m2[name1[i]]){
                    flag = 0;
                    if(m2[name2[i]]){
                        puts("NO");
                        return 0;
                    }
                    else{
                        pos[i] = 1;
                        m2[name2[i]] = 1;
                    }
                }
            }
        }
        if(flag) break;
    }
    puts("YES");
    for(int i = 1; i <= n; i++){
        if(pos[i] == 0) cout << name1[i] << endl;
        else cout << name2[i] << endl;
    }
    return 0;
}