普及组第四题难度

主体思路竟然是贪心Q_Q


链接:https://www.nowcoder.com/acm/contest/164/D
来源:牛客网

题目描述

小A有n个长度都是L的字符串。这些字符串只包含前8个小写字符,'a'~'h'。但这些字符串非常的混乱,它们几乎长得互不相同。小A想通过一些规则,让它们长得尽可能相同。小A现在有K次机会,他可以每次机会,可以选择一对字符x,y,让x,y变成等价的字符(注意这里x,y和字符'x', 'y'不是一样的,只是个代号)。注意,等价关系是有传递性的。比如小A让'a'和'b'等价, 'b'和'c'等价,那么'a'和'c'等价。
对于两个长度字符串P,Q是等价的,当且仅当对于每一位,P的字符和Q的字符都是等价的。
小A希望你告诉他,要怎么利用好这K次机会(当然可以不用完),使得尽可能多对字符串是等价的。注意每对字符串只能算一次。

输入描述:

第一行输入三个整数n,L,K。
接下来n行,每行给出一个长度为L的字符串。

输出描述:

输出一行一个整数,代表最多可能的等价的字符串对。

输入例子:
5 4 2
ccdd
babd
bdcd
ccda
bacd
输出例子:
4

-->

示例1

输入

5 4 2
ccdd
babd
bdcd
ccda
bacd

输出

4

说明

让字符a和字符d等价,字符b和字符c等价。

备注:

数据包含10个数据点。每个数据点可能有不同的特性。
对于第1,2个数据点: 保证每个字符串只包含前4个小写字母
对于第3,4个数据点:每个字符串都只包含一种字母
对于第5,6个数据点:n<=10,L<=100
对于所有数据,满足:n <= 100, L <= 1000,K <= 28,每个字符串只包含前8个小写字母

最开始考虑的是dp 然鹅发现不能做
后来打dfs只得了20
其实如果从骗分的角度来想就可以知道是贪心(就是先同化大的嘛)
证明就不证明了应该很好理解

本题还存在一个难点就是如何解决传递性的问题
于是我们可以发现一个东西叫作并查集可以把所有的数字放在一个根节点下面
同时我们可以用一个叫作拓扑排序的东西进行贪心
上代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<map>
using namespace std;
#define int long long
#define olinr return
#define _ 0
#define love_nmr 0
#define DB double
inline int read()
{
int x=,f=;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
f=-f;
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<)+(x<<)+(ch^);
ch=getchar();
}
return x*f;
}
inline void put(int x)
{
if(x<)
{
x=-x;
putchar('-');
}
if(x>)
put(x/);
putchar(x%+'');
}
int n;
int L;
int k;
struct node
{
char x;
char y;
int dis;
friend bool operator < (const node &a,const node &b)
{
return a.dis>b.dis;
}
}edge[];
int cnt;
char a[][];
int dis[][];
int fa[];
bool vis[][];
inline int findset(int x)
{
return x==fa[x]? fa[x]:fa[x]=findset(fa[x]);
}
int ans;
inline bool can(int i,int j)
{
for(int k=;k<=L;k++)
if(findset(a[i][k]-'a')!=findset(a[j][k]-'a')) return false;
return true;
}
inline void lb()
{
for(int i=;i<=;i++)
for(int j=i+;j<=;j++)
if(dis[i][j])
{
cnt++;
edge[cnt].x=i+'a';
edge[cnt].y=j+'a';
edge[cnt].dis=dis[i][j];
}
}
signed main()
{
n=read();
L=read();
k=read();
for(int i=;i<=n;i++)
scanf("%s",a[i]+);
for(int i=;i<=n;i++)
{
for(int j=i+;j<=n;j++)
{
for(int k=;k<=L;k++)
{
if(a[i][k]!=a[j][k])
{
dis[a[i][k]-'a'][a[j][k]-'a']++;
dis[a[j][k]-'a'][a[i][k]-'a']++;
}
}
}
}
lb();
for(int i=;i<=;i++)
fa[i]=i;
int tot=;
sort(edge+,edge+cnt+);
for(int i=;i<=cnt;i++)
{
int x=edge[i].x-'a';
int y=edge[i].y-'a';
int xx=findset(x);
int yy=findset(y);
if(xx!=yy)
{
fa[xx]=yy;
tot++;
}
if(tot==k) break;
}
for(int i=;i<=n;i++)
{
for(int j=i+;j<=n;j++)
{
if(vis[i][j]||vis[j][i]) continue;
if(can(i,j))
{
ans++;
vis[i][j]=vis[j][i]=true;
}
}
}
put(ans);
olinr ~~(^_^)+love_nmr;
}

2018.9.8 2018NOIP冲刺之配对的更多相关文章

  1. 2018.11.2 2018NOIP冲刺之最短公共父串

    很有意思的一个题 试题描述 给定字符串A和字符串B,要求找一个最短的字符串,使得字符串A和B均是它的子序列. 输入 输入包含两行,每行一个字符串,分别表示字符串A和字符串B.(串的长度不超过30) 输 ...

  2. 2018.10.20 2018NOIP冲刺之酒厂选址

    题目传送门 明显能够看出有一个建图求路程的优化 然而发现10000*10000爆空间QAQ 为了做一些初始化方面的优化 我们发现了一个叫做前缀和的东西 可以在环上查到两个之间的最短距离 同时还要做一些 ...

  3. 2018.10.1 2018NOIP冲刺之立体图

    2008NOIP普及组立体图 请自行百度(事实上放不下了) 图不是很清楚 下面有 [输入] 输入文件 drawing.in 第一行有用空格隔开的 2 个整数 m 和 n,表示有 m*n  个格子 (1 ...

  4. 2018.9.26 2018NOIP冲刺之栈

    最小字典序(stack) 输入序列中有 n 个正整数,栈 S 开始为空. 你每次只可以进行下面两种操作之一:① 将输入序列头端的数据移至 S 栈顶(进 S 栈): ②  将 S 栈顶元素输出并删除(退 ...

  5. EZ 2018 1 21 2018noip第五次膜你赛

    这次分数普遍偏高,而且yu'ben'ao又AK了! 但是最后一题莫名爆0让我很感伤啊(搓了1个多小时的20分暴力)! 难度偏低,主要是T2没剪枝,炸了3个点. T1 这种SB题恐怕是千年难遇了,PJ- ...

  6. EZ 2018 01 14 2018noip第四次膜你赛

    这次惨烈的炸了个精光(只有20),然后对我的OI想法造成了巨大的转折. (以上有点作,其实我只是再也不用vector存图了而已(用邻接表)) 难度很不均匀,而且题型很狗(还有结论题???) T1 坑人 ...

  7. 肖秀荣8套卷2018pdf下载|2018肖秀荣冲刺8套卷pdf下载电子版

    肖秀荣8套卷2018pdf下载|2018肖秀荣冲刺8套卷pdf下载电子版 下载链接: https://u253469.ctfile.com/fs/253469-229815828

  8. 2018软工实践—Beta冲刺(7)

    队名 火箭少男100 组长博客 林燊大哥 作业博客 Beta 冲鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调组内工作 整体软件测试 展示GitHub当日代码/文档签入记录(组 ...

  9. 2018软工实践—Beta冲刺(6)

    队名 火箭少男100 组长博客 林燊大哥 作业博客 Beta 冲鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调组内工作 最终测试文稿编写 展示GitHub当日代码/文档签入记录 ...

随机推荐

  1. WinForm和WPF颜色对象的转换

    原文:WinForm和WPF颜色对象的转换 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/huangli321456/article/details ...

  2. 关于 Swift 2.0 - 语言新特性与革新

    随着刚刚结束的 WWDC 2015 苹果发布了一系列更新,这其中就包括了令人振奋的 Swift 2.0. 这是对之前语言特性的一次大幅的更新,加入了很多实用和方便的元素,下面我们就一起来看看这次更新都 ...

  3. 【转载】FusionSphere架构详解

    FusionSphere底层使用Xen架构: 1.单台物理机上建立hypervisor系统. 2.将所有单个hypervisor系统整合起来管理使用. 安装CNA节点,所有的物理服务器都会先成为CNA ...

  4. 移花接木:借助 IViewLocationExpander 更换 ASP.NET Core View Component 视图路径

    端午节在家将一个 asp.net 项目向 asp.net core 迁移时遇到了一个问题,用 view component 取代 Html.RenderAction 之后,运行时 view compo ...

  5. style原则问题

    就近原则 1.“行内”覆盖“嵌入”,“嵌入”覆盖“外部”Style.xml <Window.Resources> <Grid.Resources> ….中间层 <Butt ...

  6. 基于IdentityServer4的单点登录——Api

    1.新建项目并添加引用 新建一个asp .net core 2.0的项目引用IdentityServer4.AccessTokenValidation 2.配置 将Api与IdentityServer ...

  7. DataTable转换为Entity(反射&&泛型)

    public static IEnumerable<T> Parse<T>(IEnumerable<DataRow> rows) where T : class, ...

  8. JS window下面的对象

    ) •Js脚本一执行就会访问服务器.超链接诶还需要点击. getElementById(), (非常常用),根据元素的Id获得对象,网页中id不能重复.也可以直接通过元素的id来引用元素,但是有有效范 ...

  9. 【C#】list 去重

    原文:[C#]list 去重 Enumerable.Distinct 方法 是常用的LINQ扩展方法,属于System.Linq的Enumerable方法,可用于去除数组.集合中的重复元素,还可以自定 ...

  10. Objective

    1.NSSet 1.是一个无序的,管理多个对象的集合类,最大特点 是集合中不允许出现重复对象,和数学上的集合含义是一 样的 2.除了无序.不许重复之外,其它功能和NSArray是一样的 2.NSArr ...