zoukankan      html  css  js  c++  java
  • hihocoder编程练习赛91:相邻字符串

    题目链接

    给定一个长度小于1e5的字符串s,s中字符全是大写英语字母。现在要寻找s中有多少组邻近的“hio”字符串,邻近的定义如下:hi距离+io距离+ho距离小于k。输入k和s,求有多少组邻近的hio。

    此题关键在于字符串是一维的序列,hi距离+io距离+ho距离必然是偶数,此距离必为hio中最左端字符和最右端字符距离的二倍。

    由此,对于任意最左端字符,只需要保证最右端字符和最左端距离不超过k/2即可。使用二分查找解决。

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    public class Main {
    int upperBound(List<Integer> a, int x) {
        int l = 0, r = a.size();
        while (l + 1 < r) {
            int mid = (l + r) >> 1;
            if (a.get(mid) <= x) {
                l = mid;
            } else if (a.get(mid) > x) {
                r = mid;
            }
        }
        if (r < a.size() && a.get(r) <= x) r++;
        return r;
    }
    
    int lowerBound(List<Integer> a, int x) {
        int l = 0, r = a.size();
        while (l + 1 < r) {
            int mid = (l + r) >> 1;
            if (a.get(mid) < x) {
                l = mid;
            } else if (a.get(mid) >= x) {
                r = mid;
            }
        }
        if (a.get(l) >= x) l--;
        return l;
    }
    
    long query(List<Integer> a, int beg, int end) {
        int b = lowerBound(a, beg), e = upperBound(a, end);
        return e - b - 1;
    }
    
    Main() {
        Scanner cin = new Scanner(System.in);
        int k = cin.nextInt();
        char[] a = cin.next().trim().toLowerCase().toCharArray();
        List<Integer> h = new ArrayList<>(a.length), i = new ArrayList<>(a.length), o = new ArrayList<>(a.length);
        List<Integer> hio = new ArrayList<>(a.length);
        for (int j = 0; j < a.length; j++) {
            if (a[j] == 'h') {
                h.add(j);
                hio.add(j);
            } else if (a[j] == 'i') {
                i.add(j);
                hio.add(j);
            } else if (a[j] == 'o') {
                o.add(j);
                hio.add(j);
            }
        }
        k /= 2;
        long s = 0;
        for (int j : hio) {
            if (a[j] == 'h') {
                s += query(i, j, j + k) * query(o, j, j + k);
            } else if (a[j] == 'i') {
                s += query(h, j, j + k) * query(o, j, j + k);
            } else if (a[j] == 'o') {
                s += query(h, j, j + k) * query(i, j, j + k);
            }
        }
        System.out.println(s);
    }
    
    public static void main(String[] args) {
        new Main();
    }
    }
    
    
  • 相关阅读:
    verilog学习(9)实战之存储器&奇偶校验
    求职经验之综合岗位三面
    求职经验之综合岗位二面
    求职经验之综合岗位
    verilog学习(8)实战之PPL与串行/解串器
    verilog学习(7)实战之扫描链
    verilog学习(6)实战4之触发器与锁存器
    verilog学习(5)实战3之计数器与bus
    verilog学习(4)实战1之基础练习
    求职经验之器件与芯片岗
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/10294854.html
Copyright © 2011-2022 走看看