H - subsequence 2

题意

要你使用前\(m\)个小写字母构造一个长度为\(n\)的字符串

有\(m*(m-1)/2\)个限制条件:

  • \(c_{1} 、c_{2}、 len\):表示除去其他非\(c_{1}、c_{2}\)之外的字母剩下的串长度为\(len\)
  • \(s\):除去其他非\(c_{1}、c_{2}\)之外的字母剩下的字符串,长度为\(len\)

需要我们根据这个限制条件构造出原串,如果不存在输出\(-1\)

思路

我们可以发现题目给了两个字母之间的相对位置。比如\(aab\),第二个\(a\)前面一定得接了个\(a\),\(b\)一定要第二个\(a\)的条件符合之后,然后第二个\(a\)放进去之后才能到\(b\)

那么对于每个字母都要先把前面的都输出完了,才能到自己,那么我们可以想到拓扑(其实是队友想的),一定要入度为零才能到本身,然后我们就可以和拓扑结合起来。

  • 定义字母:我们可以令\(a\)为\(0000\)~\(9999\)之间的数来定义(因为最多可能有\(1e^4\)个), 然后\(b\)用\(10000\)~\(19999\)这样接下去定义每个字母。
  • 建图:根据题目给的串建图, 前后建一条边。
  • 然后去跑拓扑就\(OK\)了
  • 如果你构造出来的串长度不为\(n\)就输出\(-1\)(出现循环节之类乱七八糟的情况)

一些坑点

  • 建图的时候要判断会不会出现前面出现的\(a\)有\(3\)个,这次出现的\(a\)有\(4\)个这样的情况,这样不符合条件,可以加一个数组特判一下。
  • 输入要注意\(len = 0\)的时候会输入空行,这边要处理好。(没处理好的我,\(WA\)了好多发)

一些数据

这些数据都是输出\(-1\),其实我第一组数据之前只是输入出锅了,然后导致我一直\(WA\),其实我没有输出\(-1\)也过了

3 3
ab 3
aab
ac 2
aa
bc 0 3 3
ab 3
aab
ac 1
a
bc 1
b

AC 代码

(本人太菜,代码很乱,请多见谅)

#include<bits/stdc++.h>
#define mes(a, b) memset(a, b, sizeof a)
using namespace std;
const int maxn = 1e4+10;
int n, m;
int head[maxn*50], f[30], cnt, in[maxn*50], sum[30];
char ch[maxn];
vector<int> ans;
struct Edge{
int v, next;
}e[maxn*50]; void init(){ //初始化
mes(head, -1);
mes(in, 0);
mes(sum, 0);
for(int i = 0; i <= 26; i++){
f[i] = i*10000;
}
ans.clear();
cnt = 0;
} void add(int u, int v){
e[++cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt;
} int change(int u){ //根据字母的ID转换为字母
for(int i = 0; i < 26; i++){
if(u - f[i] < 10000)
return i;
}
} int topu(){
queue<int> q;
int tot = 0;
for(int i = 0; i < m; i++){
for(int j = 0; j < sum[i]; j++){
if(!in[j+f[i]]){
q.push(j+f[i]);
}
}
}
while(!q.empty()){
int u = q.front(); q.pop();
if(change(u) >= m)
return -1;
ans.push_back(change(u));
tot++;
for(int i = head[u]; ~i; i = e[i].next){
int v = e[i].v;
in[v]--;
if(!in[v])
q.push(v);
}
}
return tot;
} int main(){
scanf("%d%d", &n, &m);
init();
int q = m*(m-1)/2;
char c1, c2;
int len;
int flag = 0;
while(q--){
char s[10];
scanf("%s%d", s, &len);
c1 = s[0];c2 = s[1];
getchar();
gets(ch);
int cnt1 = 0, cnt2 = 0, u, v; //cnt1:c1字母出现的次数
if(len > 0){ //cnt2:c2字母出现的次数
if(ch[0] == c1){
u = cnt1+f[c1-'a'];
cnt1++;
}
else{
u = cnt2+f[c2-'a'];
cnt2++;
}
for(int i = 1; i < len; i++){
if(ch[i] == c1){
v = cnt1+f[c1-'a'];
cnt1++;
}
else{
v = cnt2+f[c2-'a'];
cnt2++;
}
add(u, v);
u = v;
in[v]++;
}
}
if(!sum[c1-'a']|| sum[c1-'a'] == cnt1) //如果这次出现的次数和之前不一样,不符合条件
sum[c1-'a'] = cnt1;
else
flag = 1;
if(!sum[c2-'a']|| sum[c2-'a'] == cnt2)
sum[c2-'a'] = cnt2;
else
flag = 1;
}
int num = topu();
if(num != n || flag){
printf("-1\n");
return 0;
}
for(int i = 0; i < ans.size(); i++){
printf("%c", ans[i]+'a');
}
printf("\n");
return 0;
}

2019牛客多校第五场H - subsequence 2 拓扑的更多相关文章

  1. 牛客多校第五场 H subsequence 2 拓扑排序

    题意: 给你长度最长为1000的字符串,这个字符串中最多有10种字母,每次给你两种字母,输出这两种字母在字符串中的相对位置,问你这个字符串原本是什么样子,如果不存在则输出-1 题解: 把整个字符串看作 ...

  2. 2019牛客多校第五场 G subsequence 1 dp+组合数学

    subsequence 1 题意 给出两个数字串s,t,求s的子序列中在数值上大于t串的数量 分析 数字大于另一个数字,要么位数多,要么位数相同,字典序大,位数多可以很方便地用组合数学来解决,所以只剩 ...

  3. 2019牛客多校第五场 generator 1——广义斐波那契循环节&&矩阵快速幂

    理论部分 二次剩余 在数论中,整数 $X$ 对整数 $p$ 的二次剩余是指 $X^2$ 除以 $p$ 的余数. 当存在某个 $X$,使得式子 $X^2 \equiv d(mod \ p)$ 成立时,称 ...

  4. 2019牛客多校第五场generator2——BSGS&&手写Hash

    题目 几乎原题 BZOJ3122题解 分析 先推一波公式,然后除去特殊情况分类讨论,剩下就是形如 $a^i \equiv b(mod \ p)$ 的方程,可以使用BSGS算法. 在标准的BSGS中,内 ...

  5. 2019牛客多校第五场F maximum clique 1 最大独立集

    题意:给你n个数,现在让你选择一个数目最大的集合,使得集合中任意两个数的二进制表示至少有两位不同,问这个集合最大是多大?并且输出具体方案.保证n个数互不相同. 思路:容易发现,如果两个数不能同时在集合 ...

  6. 2019牛客多校第五场G-subsequence 1 DP

    G-subsequence 1 题意 给你两个字符串\(s.t\),问\(s\)中有多少个子序列能大于\(t\). 思路 令\(len1\)为\(s\)的子序列的长度,\(lent\)为\(t\)的长 ...

  7. 2019牛客多校第五场 B - generator 1 矩阵快速幂+十倍增+二进制倍增优化

    B - generator 1 题意 给你\(x_{0}.x_{1}.a.b.b.mod\),根据\(x_{i} = a*x_{i-1} + b*x_{i-2}\)求出\(x_{n}\) 思路 一般看 ...

  8. 2019牛客多校第五场B-generator 1(矩阵快速幂)

    generator 1 题目传送门 解题思路 矩阵快速幂.只是平时的矩阵快速幂是二进制的,这题要用十进制的快速幂. 代码如下 #include <bits/stdc++.h> #defin ...

  9. 2019 牛客多校第五场 B generator 1

    题目链接:https://ac.nowcoder.com/acm/contest/885/B 题目大意 略. 分析 十进制矩阵快速幂. 代码如下 #include <bits/stdc++.h& ...

随机推荐

  1. 关于vue2.x使用axios以及http-proxy-middleware代理处理跨域的问题

    axios现在以及是尤大大推荐使用的了,官方不在维护vue-reresource. 由于是地第一次使用axios, 在使用过程中猜了很大的坑 首先我们使用vue-cli创建的项目, 访问接口肯定是跨域 ...

  2. css 图片 和 文本 的处理

    图片 1.css3已经可以实现 img标签 和 img内图片分开处理的功能了.类似标签的背景图.   https://www.zhangxinxu.com/wordpress/2015/03/css3 ...

  3. JS 中的offset、scroll、client总结

    经常碰到offset.scroll.client这几个关键字,每次都要各种实验,这里总结一下. 两张图镇楼,随时翻阅 1. offset offset 指偏移,包括这个元素在文档中占用的所有显示宽度, ...

  4. DTED文件结构

    注:DTED层级为1时,每列总计2414字节,包含1201个高度信息:DTED层级为2时,每列总计7214字节,包含3601个高度信息:DTED层级为3时,每列包含9001个高度信息. 每列数据前八个 ...

  5. websocket 和 http的区别

    相同点: 都是基于tcp实现的,都要经过三次握手.四次挥手. 如图: 不同点: websocket 经历过连接,就可以全双工通信,不需要一直连接,降低了网络资源消耗. http 每次通讯都要连接,客户 ...

  6. 三种数据库截取字段内容&&获取字符长度的函数如下

    if(databaseutil.getValue("database").equalsIgnoreCase("sqlserver")){ list =categ ...

  7. DIV置底层或置最高层的方法下拉菜单被挡住

    网站常会用到一些 下拉菜单,,幻灯片,,,飘浮广告等. 但经常会发现.幻灯片会挡住下拉菜单或者飘浮广告微信开店等. 解决办法有下 第一,可将幻灯片所在DIV 置于最底层.添加CSS如下 style=& ...

  8. C语言博客作业12

    一.我学到的内容 二.我的收获 * https://www.cnblogs.com/asd123456/ * 我的收获:通过这一个学期的学习,我一共完成了11次作业,由最开始的第一次作业https:/ ...

  9. javaScript Queue

    function Queue() { var items = []; this.enqueue = function(element) { items.push(element) } this.deq ...

  10. mysql 用户及权限管理 允许远程连接

    mysq,功能强大的关系型数据库,它的用户管理在开发过程中当然也尤其重要,接下来就看看mysql的用户管理 1.登录数据库 mysql -uroot -p 回车 输入密码... 回车 2.登录成功后, ...