这题看了下有很多解法,一步一步来

Ⅰ . 区 间 贪 心 排 序 \color{Red}Ⅰ.区间贪心排序 Ⅰ.区间贪心排序

这是自己想的,而且似乎没看到有人用?(明明相对最容易想到)

把 每 个 字 符 串 出 现 的 每 个 位 置 记 作 一 个 区 间 \color{orange}把每个字符串出现的每个位置记作一个区间 把每个字符串出现的每个位置记作一个区间

如 果 按 照 左 端 点 排 序 , 那 就 记 录 当 前 匹 配 到 的 最 右 端 点 l a s t 如果按照左端点排序,那就记录当前匹配到的最右端点last 如果按照左端点排序,那就记录当前匹配到的最右端点last

那 么 这 个 区 间 有 贡 献 的 地 方 就 是 [ l a s t + 1 , r ] ( r 为 区 间 右 端 点 ) 那么这个区间有贡献的地方就是[last+1,r]\ \ (r为区间右端点) 那么这个区间有贡献的地方就是[last+1,r]  (r为区间右端点)

由 于 l 是 递 增 的 , 所 以 不 可 能 漏 掉 解 , 复 杂 度 O ( n ) [ 当 然 不 算 s o r t 了 h h ] 由于l是递增的,所以不可能漏掉解,复杂度O(n)[当然不算sort了hh] 由于l是递增的,所以不可能漏掉解,复杂度O(n)[当然不算sort了hh]

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e6+10;
struct p{int l,r,id;bool operator < (const p&tmp )   const{return l<tmp.l;}
}a[maxn];
string s[maxn/2];
char w[maxn];
int n,k,top,id;
int main()
{cin >> n;for(int i=1;i<=n;i++){cin >> s[++id] >> k;for(int j=1;j<=k;j++){cin >> a[++top].l;a[top].id=id,a[top].r=a[top].l+s[id].length()-1;   }}sort(a+1,a+1+top);int last=a[1].l;for(int i=1;i<=top;i++){last=max(last,a[i].l);for(;last<=a[i].r;last++){int index = last-a[i].l;w[last]=s[ a[i].id ][index];    }   }for(int j=1;j<=last-1;j++)if(w[j]>='a'&&w[j]<='z')  cout<<w[j];else   cout<<'a';
}

Ⅱ . 记 录 后 缀 跳 步 走 \color{Red}Ⅱ.记录后缀跳步走 Ⅱ.记录后缀跳步走

这种解法也很妙啊

还是把每个串出现的位置当成那个区间

一般来说需要把整个字符串一个一个填进去

考虑到很多地方已经被填过了

我们设置一个 p r e [ i ] pre[i] pre[i]数组,表示 i i i以后第一个没被填过的位置

这 样 可 以 一 直 跳 着 走 , 复 杂 度 比 O ( n ) 稍 微 差 一 点 点 这样可以一直跳着走,复杂度比O(n)稍微差一点点 这样可以一直跳着走,复杂度比O(n)稍微差一点点

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e6+10;
int n,k,pre[maxn],f[maxn],maxx;
char s[maxn],a[maxn];
int main()
{cin >> n;for(int i=0;i<maxn;i++)   pre[i]=i;for(int i=1;i<=n;i++){cin >> (a+1) >> k;int len = strlen(a+1);for(int j=1;j<=k;j++)  cin >> f[j];for(int j=1;j<=k;j++){int l=f[j],r=f[j]+len-1;maxx=max(maxx,r);while(1){if(l>=f[j]+len)   break;if(pre[l]==l)//直接赋值啦!! {s[l]=a[l-f[j]+1];pre[l]=pre[r+1];//本区间都会被填充 l++;}else{int q=pre[l];pre[l]=pre[q];//关键的一步,跳之前更新 l=q;}} }}for(int i=1;i<=maxx;i++)printf("%c",(pre[i]==i)?'a':s[i]);
}

Ⅲ . 妙 用 并 查 集 \color{red}Ⅲ.妙用并查集 Ⅲ.妙用并查集

思路和上面别无二致,就是用并查集来实现而已

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e6+10;
char ans[maxn];
int pre[maxn],maxx,n,k;
int find(int x){return pre[x]==x?pre[x]:pre[x]=find(pre[x]);
}
void join(int q,int w){pre[find(q)]=find(w);
}
int main()
{for(int i=0;i<maxn;i++)  pre[i]=i,ans[i]='a';cin >> n;for(int i=1;i<=n;i++){string s;cin >> s >> k;int len=s.size(),l;for(int j=1;j<=k;j++){cin >> l;//开始的位置 maxx=max(maxx,l+len-1);int last=find(l);//下一个没被赋值的点 while(last<l+len){ans[last]=s[last-l];join(last,last+1);last++;}}}for(int i=1;i<=maxx;i++) cout<<ans[i];
}

A. String Reconstruction(三种解法,排序贪心或跳步或并查集)相关推荐

  1. 背包问题knapsack的三种解法(Python 和 C)

    最近研究了一下0-1背包问题,题目就不复述了,大家应该都知道的. 确切的说不是三种解法而是四种解法,下面我就一一写来. 0.枚举法 这种是最简单的一种做法,当然也是时间空间复杂度最大的方法,得到的肯定 ...

  2. 三种基本排序的实现及其效率对比:冒泡排序、选择排序和插入排序

    1 public class ThreeTypesOfBaseSort { 2 // ========================== 三种基本排序的效率对比 ================== ...

  3. 【三种解法】剑指 Offer 06. 从尾到头打印链表【附完整可运行代码】

    立志用最少的代码做最高效的表达 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表 ...

  4. 【三种解法】Not so Mobile UVA - 839_19行代码AC

    立志用最少的代码做最高效的表达 Before being an ubiquous communications gadget, a mobile was just a structure made o ...

  5. 寻找两个有序数组的中位数(附上三种解法)

    目录 •写在前面 •题目 •解法一 •解法二 •解法三 •结束 •写在前面 这道题比较经典,我当时在做的时候,想出了两种解决方案,不过总感觉算法不够优美,所以找到了另一种我觉得非常精妙的解法,利用了K ...

  6. Java 中Int转String的三种方法

    JAVA 中int类型转String类型的三种通常方法: 1.String.valueOf(int i) 2.Integer.toString(int i) 3.i + ""; / ...

  7. 算法:三种简单排序算法

    排序算法比較常见的有:冒泡排序.简单选择排序.直接插入排序:希尔排序.堆排序.归并排序和高速排序算法等. 今天先学习一下前面三种比較简单的算法.排序的相关概念: ①排序的稳定性:两个或多个元素相等.排 ...

  8. [简单题]自定义取余(三种解法)C++实现

    题目链接: 点击打开原题链接 题目意思,就是标题意思. 第一种解法:(加法迭代)用加法来模拟这个(17行代码) int mod256WithoutMod(int number) {if (number ...

  9. jsp判断字符串相等_最长回文字符串三种解法

    先解释一下什么是回文字符串,比如说字符串"aba",无论是从先往后读取还是从后往前读取,结果都是一样的.当给定很长的字符串时,如何快速获取到最长的回文字符串,这也是大厂比较常见的算 ...

最新文章

  1. Git-remote Incorrect username or password ( access token )
  2. Linux捕捉信号机制之(signal,kill)、(sigaction,sigqueue)
  3. SQLServer数据库自增长标识列的更新修改操作
  4. 零基础学Java需要先具备的三项技能
  5. JavaScript闭包函数的理解与使用
  6. 2020-08-07 光纤通信第二章知识点整理
  7. 网络请求数据解析时,判断数据是否为空
  8. ecs 云服务器 管理控制台_【弹性计算】教您快速学会云服务器ECS 创建命令!
  9. 批量删除Windows7中隧道适配器的方法
  10. 自动化测试 (三) Web自动化测试原理
  11. 用 bmon 实时查看网络流量
  12. 新手入门:我的Mac文件管理使用心得
  13. HDU 2604 Queuing( 递推关系 + 矩阵快速幂 )
  14. 自由测试人Jarod的一天
  15. 315线上知识竞赛答题活动方案及模板分享
  16. Matlab小波变换双端行波测距凯伦布尔变换放射状配电网单相故障测距Simulink模型及对应程序
  17. 孟岩大大《理解矩阵一二三》语录
  18. uclinux开发概述
  19. Java中xml转义字符和gt,gte,lt,lte缩写
  20. 计算机的数学要求(?转)

热门文章

  1. 用cmake时,读取文件失败
  2. 2009年“五一”假期市民旅游指南
  3. 【全栈技术】一文了解GraphQL
  4. 译文 FaceNet: A Unified Embedding for Face Recognition and Clustering
  5. win11更改系统字体的方法
  6. zend studio 8 汉化包(安装)
  7. 模拟实现strstr函数,通俗易懂!!!
  8. 商品亲和性分析与关联规则挖掘
  9. POI Excel 上下标、下划线、粗体、斜体标签处理(sup、sub、u、strong、em的HTML标签转化到excel格式)①
  10. hls网页播放器实现