CodeForces 780D Innokenty and a Football League【模拟+贪心】
原创
©著作权归作者所有:来自51CTO博客作者Richie_LL的原创作品,请联系作者获取转载授权,否则将追究法律责任
题目链接:http://codeforces.com/contest/780/problem/D
题意:输入一个整数n,接着有n行输入,每行输入s1,s2,每一行有两种队名选择,即(1)取s1的前前个字符,(2)取s1的前两个字符,取s2的第一个字符,问你是否有取出来的每个字符串都不相同
解析:因为题目条件限制的恨死,所以直接模拟就好了,不过要记住s1如果不唯一的话,必须全都选择第二种方案,不能剩一个选择第一个方案(样例2)
我的做法是,先把s1不唯一的全部选出来,然他们选择第二种方案,然后拿map存好,接下来选择剩下来s1唯一的,如果s1有出现过,那么就采取第二种方案,全部选完以后身下的还是采取第一种方案
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <set>
#include <map>
using namespace std;
const int maxn = 1000+100;
struct node
{
int id;
string s1,s2;
string s;
}a[maxn];
int n;
map<string,int>maple;
map<string,int>maple1;
map<string,int>ans;
bool cmp(node a,node b)
{
return maple[a.s1]>maple[b.s1];
}
bool cmp1(node a,node b)
{
return a.id<b.id;
}
bool cmp2(node a,node b)
{
return ans[a.s1]>ans[b.s1];
}
int slove(int i)
{
sort(a+i,a+n,cmp2);
if(ans[a[i].s1]==0)
return i;
for(;i<n;i++)
{
if(ans[a[i].s1]==1)
{
if(ans[a[i].s2]==1)
return -1;
ans[a[i].s2] = 1;
a[i].s = a[i].s2;
}
else
break;
}
return slove(i);
}
int slove1()
{
int i = 0;
for(;i<n;i++)
{
if(maple[a[i].s1]>1)
{
if(maple1[a[i].s2]!=0)
return 0;
else
{
maple1[a[i].s2] = 1;
a[i].s = a[i].s2;
ans[a[i].s2] = 1;
}
}
else
break;
}
i = slove(i);
if(i==-1)
return 0;
for(;i<n;i++)
a[i].s = a[i].s1;
return 1;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
string t1,t2;
cin>>t1>>t2;
a[i].s1 = t1.substr(0,3);
a[i].s2 = t1.substr(0,2)+t2[0];
a[i].id = i;
maple[a[i].s1]++;
}
sort(a,a+n,cmp);
int flag = slove1();
if(flag)
{
puts("YES");
sort(a,a+n,cmp1);
for(int i=0;i<n;i++)
cout<<a[i].s<<endl;
}
else
puts("NO");
return 0;
}