D. Innokenty and a Football League(模拟)

模拟还是不到家…

设one是第一种构造方式,two是第二种构造

先把所有one相同的直接选two,因为这些人不能选one

然后考虑单独的人,单独的人可以选one也可以选two

但是不能直接选one,因为选one可能会对后面造成影响

举个例子

如果x队伍的two构造是独一无二的,但是x队伍选了one

后面假如有个y队伍,y的one构造被最开始的人用掉了,而two构造被x用掉了

就无解了,实际上让x去选two就有解

\color{Red}所以策略就出来了

扫描一遍,如果自己的one被用掉了,肯定选择two

那么自己选择了two,又会有一些人one被用掉了(自己的two等于这些人的one)

那就重复这个步骤

#include <bits/stdc++.h>
using namespace std;
const int maxn=1009;
int n;
string s1,s2;
map<string,bool>mp;
struct node{
	string f,s;
	int id,ans;
}a[maxn];
bool cop(node q,node w){
	return q.id<w.id;
}
bool sss(node q,node w)
{
	if( q.f!=w.f )	return q.f<w.f;
	return q.s<w.s;
}
int main()
{
	cin >> n;
	for(int i=1;i<=n;i++)
	{
		cin >> s1 >> s2;
		a[i].f=s1.substr(0,3);
		a[i].s=s1.substr(0,2)+s2[0];
		a[i].id=i,a[i].ans=0;
	}
	sort(a+1,a+1+n,sss);
	for(int i=2;i<=n;i++)
	{
		if( a[i].f==a[i-1].f )//first??? 
		{
			if( a[i].s==a[i-1].s )
			{
				cout << "NO";
				return 0;
			}
			a[i].ans=a[i-1].ans=2;
			mp[ a[i].s ]=mp[ a[i-1].s ]=1;
		}
	}
	bool ok=1;
	while( ok )
	{
		ok=0;
		for(int i=1;i<=n;i++)
		{
			if( a[i].ans )	continue;
			bool &t=mp[ a[i].f ];
			bool &tt=mp[ a[i].s ];
			if( t )//??????ù??? 
			{
				if( !tt )
				{
					a[i].ans=2;
					tt=1;
					ok=1;
				}
				else
				{
					cout << "NO";
					return 0;
				}
			} 
		}
	}
	cout << "YES\n";
	sort(a+1,a+1+n,cop);
	for(int i=1;i<=n;i++)
	{
	//	cout << a[i].f << " " << a[i].s << " " << a[i].id << endl;
		if( a[i].ans==2 )	cout << a[i].s << endl;
		else	cout << a[i].f << endl;
	}
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/107927809