zoukankan      html  css  js  c++  java
  • Hamming Distance(贪心,函数,构造)

    题意

    汉明距离:给定两个长度相等的字符串(a)(b),汉明距离(H(a, b) = sum_{i = 1}^{|a|}(a_i e b_i))

    现在给定两个长度相等、全由小写字母构成的字符串(a)(b)。求字典序最小的字符串(s),使得(H(a, s) = H(b, s))

    数据范围

    (1 leq T leq 100)

    (1 leq |a| leq 10000)

    思路

    定义函数(f(x) = H(a, x) - H(b, x)),我们的目标是找一个(s),使得(f(s) = 0)

    我们可以看一下(x)的每一位对函数值的贡献,不妨设可以使函数值增加(t)

    • (a_i e b_i)(s_i = a_i),则(t = 1)

    • (a_i e b_i)(s_i = b_i),则(t = -1)

    • 其他情况,(t = 0)

    因此,可以得出结果,通过调整(x),可以使得(f(x))连续变化。

    为了保证字典序最小,我们要尽可能的选择较小的字符,但是存在一个问题就是我前面选了较小的字符,但是后面无论怎么选都无法满足条件了。

    为了应对上述情况,我们采用一个预处理。就是统计字符串后缀可以使得(f(x))产生多大的变化范围。因此,定义一个(suf[i])数组,表示的是(i sim |a|)范围内(f(x))的变化幅度。

    即,统计(i sim |a|)范围内,(a_i e b_i)的个数。因此,在第(i)位从小到大枚举每个字符,如果当前的字符满足(|f(x_i)| leq suf_{i + 1}),那么就可以选这个字符。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 10010;
    
    char s1[N], s2[N];
    char ans[N];
    int suf[N];
    
    bool solve(char ch, int idx, int &dif)
    {
        int tmp = dif + (ch != s1[idx]) - (ch != s2[idx]);
        if(abs(tmp) <= suf[idx + 1]) {
            dif = tmp;
            ans[idx] = ch;
            return true;
        }
        return false;
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        for(int cas = 1; cas <= T; cas ++) {
            scanf("%s%s", s1, s2);
            memset(suf, 0, sizeof(suf));
            memset(ans, '', sizeof(ans));
            int len = strlen(s1);
            for(int i = len - 1; i >= 0; i --) {
                suf[i] = suf[i + 1];
                if(s1[i] != s2[i]) suf[i] ++;
            }
            int dif = 0;
            for(int i = 0; i < len; i ++) {
                for(int j = 0; j < 26; j ++) {
                    if(solve(j + 'a', i, dif)) break;
                }
            }
            printf("Case %d: %s
    ", cas, ans);
        }
        return 0;
    }
    
  • 相关阅读:
    HDU 2141.Can you find it?-二分
    POJ 3258.River Hopscotch-二分
    HDU 1213.How Many Tables-并查集
    HDU 1232.畅通工程-并查集
    hdu 5701 中位数计数 思路题
    codeforces 354 div2 C Vasya and String 前缀和
    codeforces 11 B.Jumping Jack 想法题
    hdu 2204 Eddy's爱好 容斥原理
    xtu 1242 Yada Number 容斥原理
    codeforces 300 div2 B.Pasha and Phone 容斥原理
  • 原文地址:https://www.cnblogs.com/miraclepbc/p/14381000.html
Copyright © 2011-2022 走看看