Технокубок 2017 - Финал (только для онсайт-финалистов) D. Innokenty and a Football League

#include <iostream>  
#include <stdio.h>  
#include <string.h>   
#include <stack>  
#include <queue>   
#include <map>  
#include <set>  
#include <vector>  
#include <math.h>  
#include <bitset>  
#include <algorithm>  

using namespace std;

#define X first
#define Y second
#define eps  1e-2
#define gcd __gcd
#define pb push_back
#define PI acos(-1.0)
#define lowbit(x) (x)&(-x)
#define bug printf("!!!!!\n");
#define mem(x,y) memset(x,y,sizeof(x))

typedef long long LL;
typedef long double LD;
typedef pair<int,int> pii;
typedef unsigned long long uLL;

const int N = 1e5+2;
const int maxn=2e3+10;
const int INF  = 1<<30;
const int mod  = 1e9+7;

string s[N][2];
int n;
char ans[N];


map<string,std::vector<pair<int,char> > >v;

std::vector<int> g[N];
std::map<string, int> MP;int cnt=0;
string MPP[N],res[N];

int match[N],vis[maxn];

bool dfs(int x){
	for(int v:g[x]){
		if(vis[v])continue;
		vis[v]=1;
		if(!match[v]||dfs(match[v])){
			match[v]=x;
			return 1;
		}
	}
	return 0;
} 


void solve(){
	int fl=0;
    cin>>n;for(int i=1;i<=n;i++) {
    	cin>>s[i][0]>>s[i][1];
    	string tp="";
    	tp=tp+s[i][0][0]+s[i][0][1]+s[i][0][2];
    	v[tp].push_back({i,s[i][1][0]});
    }
    for(auto it:v){
    	if(it.second.size()==1){
    		// ans[it.second[0].first]=it.second[0].second;
    		string s1="",s2="";
    		int pos=it.second[0].first;
    		s1=s1+s[pos][0][0]+s[pos][0][1]+s[pos][0][2];
    		s2=s2+s[pos][0][0]+s[pos][0][1]+s[pos][1][0];
    		if(MP.count(s1)==0) MP[s1]=++cnt,MPP[cnt]=s1;
    		if(MP.count(s2)==0) MP[s2]=++cnt,MPP[cnt]=s2;
    		g[it.second[0].first].push_back(MP[s1]);
    		g[it.second[0].first].push_back(MP[s2]);
    	}else{
    		// int vis[30];
    		for(int i=0;i<it.second.size();i++){
    			// if(vis[it.second[i].second]==1){
    			// 	fl=1;break;
    			// }
    			// vis[it.second[i].second]=1;
    			// ans[it.second[i].first]=it.second[i].second;
    			string s1="";int pos=it.second[i].first;

    			s1=s1+s[pos][0][0]+s[pos][0][1]+s[pos][1][0];
    			if(MP.count(s1)==0) MP[s1]=++cnt,MPP[cnt]=s1;
    			g[it.second[i].first].push_back(MP[s1]);
    		}
    	}
    }

    for(int i=1;i<=n;i++){
    	memset(vis,0,sizeof vis);
    	if(dfs(i)==0){
    		cout<<"NO"<<endl;
    		return;
    	}
    }

    for(int i=1;i<=cnt;i++){

    	if(match[i]){
    		res[match[i]]=MPP[i];
    	}
    }
    cout<<"YES"<<endl;
    for(int i=1;i<=n;i++) cout<<res[i]<<endl;

    return;
}

int main()
{
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
//    ios::sync_with_stdio(false);
    int t = 1;
    //scanf("%d",&t);
    while(t--){
    //    printf("Case %d: ",cas++);
        solve();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值