CodeForces 780D Innokenty and a Football League【模拟+贪心】

本文解析了CodeForces竞赛中一道关于字符串处理的问题。通过分析条件限制,采用模拟算法来确保选择不同的队名字符串。文章详细介绍了如何使用C++实现这一算法,包括对重复字符串的处理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接: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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值