Codeforces Round #550 (Div. 3) E 【数学】

版权声明:如需转载,记得标识出处 https://blog.csdn.net/godleaf/article/details/88959198

题目链接:http://codeforces.com/contest/1144

把字符串当作26进制数,通过 (L+R)/2 ,取中间值再转成字符串就是答案。

因为字符串的长度很大,算出来的数会溢出,所以需要一些技巧。

假设有两个字符串 abc,  efg

那么就有   \frac{26^{2} (a+e) + 26^{1} (b+f) + (c+g) }{2} 

通过不断的 % 26 得到每个位的数字。我们可以发现的是,我们其实只需要对括号内的数字 %26 就能得出结果了。

这里要注意的是括号内的数是否能被2整除,如果不能就要小心了。

因为题目说有效字符串的数量一定是奇数,我从最后一位开始不断向上取,当前位总是能被2整除的,但当前位的上一位就未必了。(最左边为最低位)

假设有 \frac{26^{2}(7)+26^{1}(7)+(8)}{2}

我们对整个数 %26的时候,除了\frac{26^{2}(7)}{2} % 26 == 0,其余的都要取余,得出位数,如果当前位上一位的括号内是偶数,那么就只需要取当前位的余就行了,否则还需要考虑上一位,其余更高位都不需要考虑,因为不管括号内是否是偶数,%26 都会等于0。

#include <bits/stdc++.h>

using namespace std;

const int Maxn = 1e6+10;
long long a[Maxn];
char ans[Maxn];

int main(void)
{
    cin.tie(0);
    cout.tie(0);
    string s, t;
    long long k;
    cin >> k;
    cin >> s >> t;
    memset(a, 0, sizeof(a));
    for(int i = k-1; i >= 0; --i) {
        a[i] += (s[i]-'a')+(t[i]-'a');
        if(i && a[i] >= 26) {
            a[i-1] += a[i]/26;
            a[i] %= 26;
        }
    }

    for(int i = k-1; i >= 0; --i) {
        if(i && (a[i-1]&1)) {
            ans[i] = (a[i]/2+13*a[i-1]) % 26;
            a[i-1] = 13*a[i-1]/26*2;
        } else ans[i] = (a[i]/2) % 26;
        ans[i] += 'a';
    }
    ans[k] = '\0';
    cout << ans << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/godleaf/article/details/88959198