给出字符串s和t,以及s的长度n的一个全排列,求按照这个排列依次删除s的字符,删到何时s中不含子序列t。

解法一:

t中的每个字符的位置在s中跳啊跳,合法的情况下t中的字符在s中的位置应该是单调递增的,因此让t中的字符在s中建的邻接表里跳啊跳就好了。

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std; #define maxs 200011
char s[maxs];int ls;
char t[maxs];int lt;
int first[],next[maxs],P[maxs];
bool vis[maxs];
bool Play(int x)
{
if (x==lt-) return ;
if (P[x+]<=P[x])
{
while (P[x+]!=- && (P[x+]<=P[x] || vis[P[x+]])) P[x+]=next[P[x+]];
if (P[x+]==-) return ;
return Play(x+);
}
return ;
}
int x;
int find(int x)
{
int L=,R=lt-;
while (L<R)
{
int mid=(L+R)>>;
if (x<=P[mid]) R=mid;
else L=mid+;
}
return L;
}
int main()
{
scanf("%s",s);ls=strlen(s);
scanf("%s",t);lt=strlen(t);
memset(first,-,sizeof(first));
for (int i=ls-;i!=-;i--)
{
int now=s[i]-'a'+;
next[i]=first[now];
first[now]=i;
}
int ans=;
for (int i=;i<lt;i++)
P[i]=first[t[i]-'a'+];
bool flag=;
for (int i=;i<lt-;i++)
if (!Play(i)) {flag=;break;}
if (flag)
{
memset(vis,,sizeof(vis));
for (int i=;i<ls;i++)
{
scanf("%d",&x);x--;
vis[x]=;
int pos=find(x);
if (P[pos]==x)
{
P[pos]=next[P[pos]];
while (P[pos]!=- && vis[P[pos]]) P[pos]=next[P[pos]];
if (P[pos]==-) break;
if (!Play(pos)) break;
}
ans++;
// for (int j=0;j<ls;j++) cout<<vis[j]<<' ';cout<<endl;
// for (int j=0;j<lt;j++) cout<<P[j]<<' ';cout<<endl;
}
}
printf("%d\n",ans);
return ;
}

该代码在随机数据下表现良好,因此如果是oi赛制可以拿到不错的分数。但是理论复杂度是n2的,而且存在aaaa……这样的数据使得t中每个字符都要跳n次。

解法二:

我们要在排列中找一个位置,它左边的都符合某个条件,而右边都不符合。二分!!

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
//#include<iostream>
using namespace std; #define maxs 200011
char s[maxs];int ls;
char t[maxs];int lt;
int a[maxs];
bool vis[maxs];
int main()
{
scanf("%s%s",s,t);
ls=strlen(s),lt=strlen(t);
for (int i=;i<ls;i++) scanf("%d",&a[i]),a[i]--;
int L=,R=ls-;
while (L<R)
{
int mid=(L+R+)>>;
memset(vis,,sizeof(vis));
for (int i=;i<mid;i++) vis[a[i]]=;
int j=;
for (int i=;i<ls;i++)
if (j<lt && s[i]==t[j] && !vis[i]) j++;
if (j==lt) L=mid;
else R=mid-;
}
printf("%d\n",L);
return ;
}

CF778A:String Game的更多相关文章

  1. 深入理解Java:String

    在讲解String之前,我们先了解一下Java的内存结构. 一.Java内存模型 按照官方的说法:Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配. JVM主要管理两 ...

  2. c++:string函数

    string类的构造函数:string(const char *s);    //用c字符串s初始化string(int n,char c);     //用n个字符c初始化此外,string类还支持 ...

  3. 原生JS:String对象详解

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  4. Java:String和Date、Timestamp之间的转

    Java:String和Date.Timestamp之间的转 一.String与Date(java.util.Date)互转 1.1 String -> Date String dateStr  ...

  5. Java:String和Date、Timestamp之间的转换

    一.String与Date(java.util.Date)互转 1.1 String -> Date String dateStr = "2016-9-28 12:25:55" ...

  6. java:String使用equals和==比较的区别

    原文链接:http://www.cnblogs.com/tinyphp/p/3768214.html "=="操作符的作用 1.用于基本数据类型的比较 2.判断引用是否指向堆内存的 ...

  7. 【转】Java魔法堂:String.format详解

    Java魔法堂:String.format详解     目录     一.前言    二.重载方法     三.占位符     四.对字符.字符串进行格式化     五.对整数进行格式化     六. ...

  8. Java:String、StringBuffer和StringBuilder的区别

    1 String String:字符串常量,字符串长度不可变.Java中String是immutable(不可变)的. String类的包含如下定义: /** The value is used fo ...

  9. leetcode:String to Integer (atoi)

    Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cases. ...

随机推荐

  1. k-window的关闭与打开设置

    // 打开弹框窗口 public showKwinDow() { const that = this as any; // 设置窗口居中 that.$refs['setAddEdit'].widget ...

  2. 开启server-status失败

    近日在配置监控宝的apache监控老是出错,经过研究发现如下: 下面先做一些简要的介绍,以防以后查看之用. 一.server-status是什么?二.如何打开server-status?三.serve ...

  3. Jmeter官网文档翻译

    Jmeter目录 入门 1.0概述 测试计划建设 负载测试运行 负载测试分析 开始吧 1.1要求 1.1.1 Java版本 1.1.2操作系统 1.2可选 1.2.1 Java编译器 1.2.2 SA ...

  4. centos7 取消Ctrl+Alt+Del重启功能

    转载:http://www.cnblogs.com/huangjc/p/4536620.html Linux默认允许任何人按下Ctrl+Alt+Del来重启系统.但是在生产环境中,应该停用按下Ctrl ...

  5. c语言 错误记录

    1.预处理错误 #include <>   //系统内部的 #include ""   // 自定义的 遇到 not find------解决方案:gcc -I 跟查找 ...

  6. js数组常用方法整理

    学疏才浅,若有不对的地方,希望大家可以帮忙指正出来. 1. Array.push(),向数组的末尾添加一个或多个元素,并返回新的数组长度.原数组改变. 2. Array.pop(),删除并返回数组的最 ...

  7. HTML页面中5种超酷的伪类选择器:hover效果

    想在自己的网站中应用超酷的hover效果吗?也许你可以从如下的这些实例中获得一些灵感,如果你喜欢这些效果,也可以直接拷贝代码并应用到你的站点. 给平淡的站点带来活力 hover效果能给网页增加一些动态 ...

  8. 牛客OI赛制测试赛2 C 数组下标

    链接:https://www.nowcoder.com/acm/contest/185/C来源:牛客网 题目描述 给出一个数列 A,求出一个数列B. 其中Bi   表示 数列A中 Ai 右边第一个比 ...

  9. luogu 数列找不同-莫队

    https://www.luogu.org/problemnew/show/P3901 了解过莫队的人应该都清楚,莫队是一个优化的暴力,可以在相对暴力比较优的时间中,求出一段序列内的某些性质(例:数字 ...

  10. Memcached的安装和应用

    Memcached的安装 1.安装libeventlibevent是一个事件触发的网络库,适用于windows.linux.bsd等多种平台,内部使用 select.epoll.kqueue等系统调用 ...