zoukankan      html  css  js  c++  java
  • codeforces 778A String Game&&汕头市队赛SRM06A

    A 撕书 SRM 06

    背景&&描述

            游行寺汀正在杀书。
            书总共有n页,每页都可以看作是一个小写英文字母,所以我们可以把书看成长度为n的字符串s。
            琉璃静静地在旁边看着。根据他对汀的了解,汀+1s只会撕一页。令a_{i}表示第i秒撕的是哪一页,显然a是1..n的一个排列。
            琉璃突然对s的一个非空子序列t产生了兴趣。他想知道,最多在汀撕多少页之后,t仍然是剩下的书的某个子序列。

     

    输入格式

            第一行一个字符串,表示s

            第二行一个字符串,表示t

            第三行n个整数(n为s的长度),表示a

    输出格式

    一个整数,表示最多在汀撕多少页之后,t仍然是剩下的书的某个子序列。

    样例输入

    sbkitssakitsak
    kisaki
    1 14 13 2 6 12 9 10 5 3 8 4 7 11
    

    样例输出

    6

    数据范围与约定

    • 对于100%的数据:1leq nleq 2*10^5

    样例解释

    6s后,剩下的书为kitsakit,此时kisaki还是书的子序列。第7s撕掉第二个k后就不是了。


    我上的是我们市队赛的题面

    跟codeforces的唯一区别是那个没有保证给的一定是书的子序列

    把二分边界改一下就好了

    这题得orz一波yy大爷

    我自己根本没想出要二分

    以后这种求最大最小的得往二分上面想啊

    yy大爷的处理也很巧妙啊

    想到要记录每个位置是哪一次删的

    这样直接扫一遍就可以了

    我本来还想着要去删的委屈

    然后二分最后跨度为1的时候如果写在二分里面挺难处理的(起码我感觉是)

    所以我直接break出来判一下就好了

    #include<cstdio>
    #include<cstring>
    const int N=200007;
    char a[N],b[N];
    int t[N];
    int n,m;
    bool check(int x)
    {
    	for(int i=1,j=1;i<=n;i++)
    	{
    		if(t[i]<=x)	continue;
    		if(a[i]==b[j])	j++;
    		if(j==m+1)	return 1;
    	}
    	return 0;
    }
    int main()
    {
    	scanf("%s %s",a+1,b+1);
    	n=strlen(a+1),m=strlen(b+1);
    	int k;
    	for(int i=1;i<=n;i++)	scanf("%d",&k),t[k]=i;
    	int ll=0,rr=n;
    	while(rr-ll>1)
    	{
    		int mid=(ll+rr)>>1;
    //		printf("%d %d %d
    ",ll,rr,mid);
    		if(check(mid))	ll=mid;
    		else rr=mid-1;
    	}
    	if(check(rr))	printf("%d
    ",rr);
    	else printf("%d
    ",ll);
    	return 0;
    }


  • 相关阅读:
    C#冒泡排序--详解
    盘古搜索--实例解析
    ajax提交表单序列化(serialize())数据
    随机数大揭秘
    静态代码块(主要是注意执行顺序)
    单例模式
    递归
    vue路由嵌套(邹文丰)
    vue computed和 methods、 watch 区别(邹文丰)
    vuex状态管理mutations,getters,actions总结(邹文丰)
  • 原文地址:https://www.cnblogs.com/Brian551/p/7353010.html
Copyright © 2011-2022 走看看