Codeforces 780D-Innokenty and a Football League

Innokenty and a Football League
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Examples
input
2
DINAMO BYTECITY
FOOTBALL MOSCOW
output
YES
DIN
FOO
input
2
DINAMO BYTECITY
DINAMO BITECITY
output
NO
input
3
PLAYFOOTBALL MOSCOW
PLAYVOLLEYBALL SPB
GOGO TECHNOCUP
output
YES
PLM
PLS
GOG
input
3
ABC DEF
ABC EFG
ABD OOO
output
YES
ABD
ABE
ABO
Note

In the first sample Innokenty can choose first option for both clubs.

In the second example it is not possible to choose short names, because it is not possible that one club has first option, and the other has second option if the first options are equal for both clubs.

In the third example Innokenty can choose the second options for the first two clubs, and the first option for the third club.

In the fourth example note that it is possible that the chosen short name for some club x is the same as the first option of another club yif the first options of x and y are different.


题意:某人需要给若干球队选择队名缩写。已知每个球队的名字必然是<team name><hometown neme>的形式。取队名缩写的规则是固定的,只有两种:选择 team name 的前三个字母作为队名缩写或选择 team name 的前两个字母与 hometown name 的首字母组成队名缩写。每个队的队名缩写都可以从两种中任选一种,问能够使得每个队最终的队名缩写均不同。如果 x 的第一类队名缩写为 x.fi,第二类队名缩写为 x.se,并且x.fi== y.fi,若 x 选择了 x.se作为最终的队名缩写,并且如果 x 的第一类队名缩写为 x.fi,第二类队名缩写为 x.se,那么其他队伍均不能以 y.fi 作为最终的队名缩写。如果是 y.se==x.fi的话,则不触发这一禁制规则。

解题思路:如果存在 a 与 b,使得 a.fst == b.fst ,那么,两者均不能选择第一类队名作为其最终队名缩写。先对出现第一类队名重复的队单独处理。它们都只能用第二类队名缩写作为最终的队名缩写,同事判断这些第二类队名是否出现重复,如果出现重复,则必然无解;否则继续。然后考虑剩下的第一类队名均唯一的那些队。因为它们的第一类队名不会重复,直接选择第一类队名作为最终队名最简单。由于最终队名也不能出现重复,因此之前选择的最终队名可能对这些剩下的队产生影响,排序后获得剩下队伍中的第一类队名与之前确定的队名重复的队名。它们也只能选择第二类队名作为最终队名。然后不断循环,直到没有队未处理剩下的队中的第一类队名不与之前任意队伍的最终队名相同 ,这些队伍的最终队名即为第一类队名。


#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <climits>

using namespace std;

#define LL long long
const int INF=0x3f3f3f3f;

struct node
{
    string fi,se,ans;
    int id;
}x[1009];
int n;
map<string,int>cntfi,cntse,cnt;

bool cmp(node a,node b)
{
    return cntfi[a.fi]>cntfi[b.fi];
}

bool cmp_cnt(node a,node b)
{
    return cnt[a.fi]>cnt[b.fi];
}

bool cmp_id(node a,node b)
{
    return a.id<b.id;
}

int f(int k)
{
    sort(x+k,x+n,cmp_cnt);
    if(!cnt[x[k].fi]) return k;
    for(;k<n;k++)
    {
        if(cnt[x[k].fi])
        {
            if(cnt[x[k].se]) return -1;
            x[k].ans=x[k].se;
            cnt[x[k].ans]=1;
        }
        else break;
    }
    return f(k);
}

bool solve()
{
    int i=0;
    for(;i<n;i++)
    {
        if(cntfi[x[i].fi]>1)
        {
            if(cntse[x[i].se]==1) return false;
            else x[i].ans=x[i].se,cntse[x[i].ans]=1,cnt[x[i].ans]=1;
        }
        else break;
    }
    i=f(i);
    if(i==-1) return false;
    for(;i<n;i++) x[i].ans=x[i].fi;
    return true;
}

int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=0;i<n;i++)
        {
            cin>>x[i].fi>>x[i].se;
            x[i].id=i;
            x[i].se=x[i].fi.substr(0,2)+x[i].se[0];
            x[i].fi=x[i].fi.substr(0,3);
            cntfi[x[i].fi]++;
        }
        sort(x,x+n,cmp);
        bool flag=solve();
        printf("%s\n",flag?"YES":"NO");
        if(flag)
        {
            sort(x,x+n,cmp_id);
            for(int i=0;i<n;i++) cout<<x[i].ans<<endl;
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值