codeforces D. Innokenty and a Football League

来源:互联网 发布:网络教育和开放教育 编辑:程序博客网 时间:2024/06/06 09:36

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard 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:

the short name is the same as three first letters of the team’s name, for example, for the mentioned club it is “DIN”,
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.

题意:为给你每个俱乐部的两个大名,为每个俱乐部取个小名,小名两种做法,一取第一个大名的前三个字母,二:取第一个大名的前两个字母,第二个大名的第一个字母。这个要求我现在才看懂。就是第一个方法的小名与别的第一个小名有重复是不可以的,如果别人选择了第一个小名,那么另一个人的第二个小名相同的话,也不可以用。但是相反,如果是有两个人第二个小名相同 其中一个人可以选择第二个小名

// 4
// PLAYFOOTBALL MOSCOW
// PLAYFOOTBALL SOSCOW
// PLSYVOLLEYBALL APB
// GOGO TECHNOCUP
// PLM
// PLS
// PLA
// GOT

。。。这道题有bug
4
PLCYFOOTBALL MOSCOW
PLHYFOOTBALL AOSCOW
PLGO TECHNOCUP
PLGYVOLLEYBALL APB
输出NO 也可以过 但是明明有答案。。
// PLC
// PLH
// PLT
// PLA

出题太不严谨了

卡过的代码

#include <bits/stdc++.h>using namespace std;set <string> ss,ss2;vector<string> ans;int main(){    int n;    cin >> n;    string s1, s2;    string cmp1,cmp2;    for(int i = 1; i <= n; i++)    {        cin >> s1 >> s2;        cmp1 = s1.substr(0,3);        cmp2 = s1.substr(0,2) + s2[0];        if(ss.count(cmp2))        {            if(ss2.count(cmp1)||ss.count(cmp1))            {                for(int i=0;i<ans.size();i++)                    cout<<ans[i]<<endl;                cout<<"NO"<<endl;                return 0;            }            ss.insert(cmp1);            ans.push_back(cmp1);        }        else        {            ss.insert(cmp2);            ss2.insert(cmp1);            ans.push_back(cmp2);        }    }        cout << "YES" << endl;        for(int i = 0; i < ans.size(); i++)            cout << ans[i] << endl;}

正确代码

解决冲突的两种方法,如果第一个小名已经有了,那么选择第二个小名如果第二个小名冲突,那么更改这个小名以前所在位置看是否能改到第一个小名,如果不能,那么更改当前的第一个小名的以前的小名位置,看能不能改成第二个,-1的意思是如果本来有队伍首选,后来改成了次选,但是别的队伍不能用这个作为首选了,所以要把以前用首选是这个的人改成二选,并判断是否可以,只有当要改的已经是二选的时候,ok改为0。但是如果是二选是别人曾经的首选,那么是没有问题的,而且不用继续延伸。

#include<cstring>#include<cstdio>#include<string>#include<algorithm>#include<iostream>#include<map>using namespace std;map<string,int> mp;string fir[1010],sec[1010],s1,s2;int now[1010],n,ok=1;void ins(int x){    int y;    if (!mp.count(sec[x])) mp[sec[x]]=x;    else    {        y=mp[sec[x]];        mp[sec[x]]=x;        if (y==-1) return; //改过不用再改        if (now[y]==2) ok=0;        else        {            now[y]=2;            ins(y);        }    }}int main(){    int y;    scanf("%d",&n);    for (int i=1;i<=n;i++)    {        cin>>s1>>s2;        fir[i]=s1.substr(0,3);        sec[i]=s1.substr(0,2)+s2[0];    }    for (int i=1;i<=n&&ok;i++)        if (!mp.count(fir[i])) mp[fir[i]]=i,now[i]=1;        else        {            now[i]=2;            ins(i);//判断i的二选是否可行            y=mp[fir[i]];//以前用这个首选作为最终选择的 要改            if (y==-1) continue; //y==-1 就是已经改过的 不            //用再改           if (now[y]==1)             {                mp[fir[i]]=-1;//帮他改,然后以后不用再改                now[y]=2;                ins(y);            }        }    if (ok)    {        cout<<"YES"<<endl;        for (int i=1;i<=n;i++)            if (now[i]==1) cout<<fir[i]<<endl;            else cout<<sec[i]<<endl;    }    else cout<<"NO"<<endl;}
0 0