CodeForces-1009G Allowed Letters

Allowed Letters(贪心+霍尔定理)

题意:

给定一个字符串,给出个条件,每个条件要求位置只能填某些指定的字符。要求输出满足条件且字典序最小的,否则输出。保证字符只包含

题解:

首先可以想到可以用最大流解决,从源点个位置依次连一条流量为的边,在对个条件,每个向对应的几个字符都连一条流量为的边,最终个字符都向汇点连一条的边,最终只需要跑一遍最大流判断最大流是否为即可。这样确实可以判断当前字符串是否满足条件,但是考虑到最坏情况要跑次最大流,肯定会超时,因此想到可能需要优化一下判断字符串满足条件的方法。

霍尔定理
设二分图的两部分为,且。则定理描述为:二分图存在完美匹配,等价于对于的任意子集,与它们中任意点相连的的结点个数

那么不妨统计下每个中每种字符集的满足位置的数量,只要对于当前中字符集都满足条件,那么肯定存在一个完美匹配,即存在一种字符串分配方案满足条件。考虑到字典序最小,只需要从头开始填字符,每次都从枚举判断是否满足条件。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int n,m,cnt[10],f[maxn][1<<6],val[maxn];
char s[maxn],t[10],res[maxn];
bool check(int id)
{
    for(int i=0; i<(1<<6); i++)
    {
        int sum=0;
        for(int j=0; j<6; j++)
            if((i>>j&1))
                sum+=cnt[j];
        if(sum<f[id][i])
            return 0;
    }
    return 1;
}
int main()
{
    scanf("%s",s+1);
    m = strlen(s+1);
    for(int i=1; i<=m; i++)
        cnt[s[i]-'a']++;
    scanf("%d",&n);
    for(int i=1,x; i<=n; i++)
    {
        scanf("%d %s",&x,t+1);
        for(int j=1; t[j]; j++)
            val[x]|=(1<<(t[j]-'a'));
    }
    for(int i=m; i>=1; i--)
    {
        if(!val[i])
            val[i]=(1<<6)-1;
        for(int j=0; j<(1<<6); j++)
        {
            f[i][j]=f[i+1][j];
            if((j&val[i])==val[i])
                f[i][j]++;
        }
    }
    for(int i=1; i<=m; i++)
    {
        int flag=0;
        for(int j=0; j<6; j++)
        {
            if(!cnt[j]||(val[i]>>j&1)==0)
                continue;
            cnt[j]--;
            if(check(i+1))
            {
                flag=1;
                res[i]='a'+j;
                break;
            }
            else
                cnt[j]++;
        }
        if(!flag)
        {
            puts("Impossible");
            return 0;
        }
    }
    printf("%s\n",res+1);
    return 0;
}
全部评论

相关推荐

关于“实习生工资多少才算正常”,其实并没有一个放之四海而皆准的标准,但如果结合一线城市的生活成本、工作强度以及实习本身创造的价值来看,我个人认为6000&nbsp;元左右应当是一个基本及格线,也就是每天&nbsp;200&nbsp;多元。如果能达到&nbsp;300、400&nbsp;元一天,甚至更高,那无疑是更理想的状态。首先,从现实成本看,房租、通勤、餐饮几乎都是刚性支出。低于这个水平的实习,往往意味着实习生需要用家庭或存款“倒贴”工作,这在长期来看并不合理。实习本质上是学习,但并不等于“廉价劳动力”,更不应该是经济压力的来源。其次,愿意给实习生更高薪资的公司,通常不会是差公司。这至少说明两点:一是公司资金相对充足,不是靠压缩人力成本勉强维持;二是公司认可实习生的价值,希望你真正参与业务、创造产出,而不是只做边角料工作。很多高薪实习往往伴随着更规范的培养体系、更高的信息密度和更真实的项目经验。当然,高工资并不等于一切,但它往往是一个重要信号。能给到&nbsp;300、400&nbsp;元一天甚至更多的公司,往往对效率、能力和长期发展更有追求,也更可能处在一个有前景的赛道中。总结来说,实习工资不仅是钱的问题,更是公司态度、实力和发展前景的体现。在条件允许的情况下,争取一份“付得起你时间”的实习,本身就是一种理性选择。
北国牛马:你是不是忘了你一周只能上五天班,月薪6000那你日薪就得300了,日薪200一个月也就4000,也就刚好覆盖生活成本了
实习生工资多少才算正常?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务