• Solution -「ExaWizards 2019 C」Snuke and Wizards


    (mathcal{Description})

      Link.

      给定一个长度为 (n) 的字符串 (s),每个字符上初始有一张卡片。(q) 次操作,每次指定 (s) 中字符为 (c) 的所有位置上的所有卡片向左或向右移动一位,移出字符串则消失。求操作完成后剩下的卡片数量。

      (nle10^5)

    (mathcal{Solution})

      脑补了很多优雅的做法,卡了好久才发现这道题其实很蠢 qwq……

      显然,消失的卡片是原字符串上卡片的一段前缀和一段后缀,直接二分边界检查即可。

      复杂度 (mathcal O(nlog n))

      哎呀我何必这么水题解呢。

    (mathcal{Code})

    /* Clearink */
    
    #include <cstdio>
    
    const int MAXN = 2e5;
    int n, q;
    char s[MAXN + 5], let[MAXN + 5], way[MAXN + 5];
    
    inline char rlet () {
    	char ret = getchar ();
    	for ( ; ret < 'A' || 'Z' < ret; ret = getchar () );
    	return ret;
    }
    
    inline int check ( int x ) {
    	for ( int i = 1; i <= q && 1 <= x && x <= n; ++ i ) {
    		if ( let[i] == s[x] ) {
    			x += way[i] == 'L' ? -1 : 1;
    		}
    	}
    	return x < 1 ? -1 : x > n;
    }
    
    int main () {
    	scanf ( "%d %d %s", &n, &q, s + 1 );
    	for ( int i = 1; i <= q; ++ i ) let[i] = rlet (), way[i] = rlet ();
    	int l = 0, r = n, ans = n;
    	while ( l < r ) {
    		int mid = l + r + 1 >> 1;
    		if ( !~check ( mid ) ) l = mid;
    		else r = mid - 1;
    	}
    	ans -= l ++, r = n + 1;
    	while ( l < r ) {
    		int mid = l + r >> 1;
    		if ( check ( mid ) == 1 ) r = mid;
    		else l = mid + 1;
    	}
    	ans -= n - l + 1;
    	printf ( "%d
    ", ans );
    	return 0;
    }
    

    (mathcal{Details})

      一个思路一定要连贯地想到困境再舍弃,不同思路来回跳跃太浪费时间啦!

  • 相关阅读:
    css font-family(字体样式)
    360浏览器兼容模式,页面不能正常渲染
    SVN 如何更换IP地址
    Update 出现在的问题
    安装node-sass
    vue 里面输出带标签的html
    css 内容超出宽度自动换行
    js 判断各种数据类型
    Java_面向对象三大特征
    Java_基础(二)
  • 原文地址:https://www.cnblogs.com/rainybunny/p/13979936.html
Copyright © 2020-2023  润新知