Codeforces Round #403 D. Innokenty and a Football League(思维+模拟)

来源:互联网 发布:法兰绒格子衬衫 知乎 编辑:程序博客网 时间:2024/06/05 19:23

D. Innokenty and a Football League

Description

Innokenty is a president of a new football league in Byteland. The first task he should do is to assign short names to all clubs to be shown on TV next to the score. Of course, the short names should be distinct, and Innokenty wants that all short names consist of three letters.

Each club’s full name consist of two words: the team’s name and the hometown’s name, for example, “DINAMO BYTECITY”. Innokenty doesn’t want to assign strange short names, so he wants to choose such short names for each club that:

  1. the short name is the same as three first letters of the team’s name, for example, for the mentioned club it is “DIN”,
  2. or, the first two letters of the short name should be the same as the first two letters of the team’s name, while the third letter is the same as the first letter in the hometown’s name. For the mentioned club it is “DIB”.

Apart from this, there is a rule that if for some club x the second option of short name is chosen, then there should be no club, for which the first option is chosen which is the same as the first option for the club x. For example, if the above mentioned club has short name “DIB”, then no club for which the first option is chosen can have short name equal to “DIN”. However, it is possible that some club have short name “DIN”, where “DI” are the first two letters of the team’s name, and “N” is the first letter of hometown’s name. Of course, no two teams can have the same short name.

Help Innokenty to choose a short name for each of the teams. If this is impossible, report that. If there are multiple answer, any of them will suit Innokenty. If for some team the two options of short name are equal, then Innokenty will formally think that only one of these options is chosen.

Input

The first line contains a single integer n (1 ≤ n ≤ 1000) — the number of clubs in the league.

Each of the next n lines contains two words — the team’s name and the hometown’s name for some club. Both team’s name and hometown’s name consist of uppercase English letters and have length at least 3 and at most 20.

Output

It it is not possible to choose short names and satisfy all constraints, print a single line “NO”.

Otherwise, in the first line print “YES”. Then print n lines, in each line print the chosen short name for the corresponding club. Print the clubs in the same order as they appeared in input.

If there are multiple answers, print any of them.

题意

某人需要给若干球队选择队名缩写。已知每个球队的名字必然是 <team name> <hometown name> 的形式。取队名缩写的规则是固定的,只有两种:

  1. 选择 team name 的前三个字母作为队名缩写
  2. 选择 team name 的前两个字母与 hometown name 的首字母组成队名缩写。

每个队的队名缩写都可以从两种中任选一种,问能够使得每个队最终的队名缩写均不同。

同时,题面中有额外要求,如果 x 的第一类队名缩写为 x.fst ,第二类队名缩写为 x.sec。若 x 选择了 x.sec 作为最终的队名缩写,那么其他队伍均不能以 y.fst 作为最终的队名缩写,如果 x.fst == y.fst 的话。当然,如果是 y.sec ==x.fst 的话,则不触发这一禁制规则。

分析

思维+模拟即可解决。

由于题面的额外要求,将问题极大的简化了。根据其额外要求,可以得出一个简单结论,如果存在 a 与 b,使得 a.fst == b.fst ,那么,两者均不能选择第一类队名作为其最终队名缩写。故首先对出现第一类队名重复的队单独处理(我的代码中用 map 计数加 sort 实现)。由于它们都只能用第二类队名缩写作为最终的队名缩写。因此线性扫描这些的第二类队名,如果出现重复,则必然无解;否则继续。

之后,考虑剩下的第一类队名均唯一的那些队。按照简单的思路考虑,由于它们的第一类队名不会重复,直接选择第一类队名作为最终队名最简单。但是,注意: 由于最终队名也不能出现重复,因此上述所选择的最终队名可能对这些剩下的队产生影响,故继续 map 计数加 sort 获得剩下队伍中的第一类队名与上面队伍的第二类队名重复的队。它们也只能选择第二类队名作为最终队名。加以判断。然后一遍一遍循环,直到没有队未处理剩下的队中的第一类队名不与之前任意队伍的最终队名相同 ,这些队伍的最终队名即为第一类队名。

最后,重新按照输入的顺序进行排序,输出答案即可。

代码

#include<bits/stdc++.h>using namespace std;const int N = 1000 + 10;struct Name {    string fst, sec, ans;    int idx;} src[N];int n;map<string, int> cntFst, cntSec, sht;bool cmp(Name a, Name b) {    return cntFst[a.fst] > cntFst[b.fst];}bool cmp_sht(Name a, Name b) {    return sht[a.fst] > sht[b.fst];}bool cmp_idx(Name a, Name b) {    return a.idx < b.idx;}int round(int idx){    sort(src+idx, src+n, cmp_sht);    if(sht[ src[idx].fst ] == 0)    return idx;    for(;idx<n;idx++)    {        if(sht[ src[idx].fst ] == 1)        {            if(sht[ src[idx].sec ] == 1)                return -1;            src[idx].ans = src[idx].sec;            sht[ src[idx].ans ] = 1;        }        else    break;    }    return round(idx);}bool solve(){    int idx = 0;    for(;idx<n;idx++)    {        if(cntFst[ src[idx].fst ] > 1)        {            if(cntSec[ src[idx].sec ] == 1)                return false;            else                src[idx].ans = src[idx].sec,                cntSec[ src[idx].ans ] = 1,                sht[ src[idx].ans ] = 1;        }        else    break;    }    idx = round(idx);    if(idx == -1)   return false;    for(;idx < n;idx++)        src[idx].ans = src[idx].fst;    return true;}int main(){    scanf("%d",&n);    for(int i=0;i<n;i++)    {        cin>>src[i].fst>>src[i].sec;        src[i].idx = i;        src[i].sec = src[i].fst.substr(0, 2) + src[i].sec[0];        src[i].fst = src[i].fst.substr(0, 3);        cntFst[ src[i].fst ]++;    }    sort(src, src+n, cmp);    bool flg = solve();    printf("%s\n",flg ? "YES":"NO");    if(flg)    {        sort(src, src+n, cmp_idx);        for(int i=0;i<n;i++)            cout<<src[i].ans<<endl;    }}
0 0
原创粉丝点击