给出字符串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. LN : leetcode 746 Min Cost Climbing Stairs

    lc 746 Min Cost Climbing Stairs 746 Min Cost Climbing Stairs On a staircase, the i-th step has some ...

  2. STM32 modbus CRC16校验

    typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef int int32_t; const uint16_t ...

  3. VTK教程系列:VTK基础及应用开发教程

    由于OpenCV不能使用,只能使用VTK库的图像处理库,暂时还没有找到其他可以全面替代的库: CSDN东灵工作室:http://blog.csdn.net/www_doling_net/article ...

  4. subprocess使用小方法

    import subprocess     def create_process(cmd):     p = subprocess.Popen(cmd, shell=True, stdout=subp ...

  5. DBMS的工作模式

    数据库管理系统(DBMS)是指数据库系统中对数据进行管理的软件系统,它是数据库系统的核心组成部分,对数据库的一切操作(增删改查)都是通过DBMS进行的 DBMS的工作模式如下: 1>接受应用程序 ...

  6. 汇编3栈帧,参数传递,串操作,混合汇编,x64,asm文件

    基础知识2 选择结构 通过判断 + 条件跳转指令来实现 循环结构 通过判断 + 条件跳转指令来实现(会有一个向上跳转的语句) 函数调用约定 C调用约定: 由外部平衡栈 标准调用约定 : 由函数内部平衡 ...

  7. dig - 发送域名查询信息包到域名服务器

    SYNOPSIS(总览) dig [@ server ] domain [Aq query-type ] [Aq query-class ] [+ Aq query-option ] [-Aq dig ...

  8. navicat 链接数据库查看的工具 可以同时查看各种数据库 MySql SqlServer

    navicat 链接数据库查看的工具 Navicat_Premium_10.0.11.0_XiaZaiBa

  9. js 将页面保存为图片

    <!DOCTYPE html><html><head><title>保存为images</title><meta charset=&q ...

  10. CentOS7.4搭建kafka单结点和集群

    操作系统选择 CentOS7.4x86-64(操作系统的x86_64是跟CPU有关的,最早AMD公司开发出了一款向下兼容x86CPU,向上又扩充了指令集,具有了64位CPU的特性,这款CPU后来改名为 ...