Atcoder CODE FESTIVAL 2017 qual C C

题目链接

题意

给定字符串(s),可以在其中任意位置插入字符(x). 问能否得到一个回文串,若能,需插入多少个(x).

思路

首先统计出现次数为奇数的字符(cnt).

(cntgeq1)

显然无解

(cnt==1)

则回文串长度为奇数。找到中间位置,向两边check.

(cnt==0)

则回文串长度为偶数。找到中间的两个位置,向两边check.

// 很生气...打比赛时活生生将(n)跟在了(cnt)后面定义,于是用一个(char)类型的(n)去wa了一个小时,改写了好几版代码。

Code 1.

#include <bits/stdc++.h>
#define maxn 100010
using namespace std;
typedef long long LL;
char s[maxn];
int cnt[256], n;
LL ans;
bool check(int i, int j) {
        ans = 0;
        for (; i>=0, j<n; ) {
            if (s[i]==s[j]) {--i, ++j; continue; }
            if (s[i]!='x'&&s[j]!='x') return 0;
            if (s[i]=='x') ++ans, --i;
            else if (s[j]=='x') ++ans, ++j;
        }
        if (i==-1) {
            ans += n-j;
            for (; j < n; ++j) if (s[j]!='x') {return 0; }
        }
        if (j==n) {
            ans += i+1;
            for (; i >= 0; --i) if (s[i]!='x') { return 0; }
        }
        return 1;
}
int main() {
    scanf("%s", s);
    n = strlen(s);
    for (int i = 0; i < n; ++i) ++cnt[s[i]];
    char ch;
    int tot = 0, odd = 0;
    for (int i = 'a'; i <= 'z'; ++i) {
        if (i == 'x') continue;
        if (cnt[i] & 1) ++odd;
        tot += cnt[i];
    }
    if (odd > 1) { puts("-1"); return 0;}
    if (tot == 0) { puts("0"); return 0; }
    (tot /= 2) += 1;
    int cur=0, i = 0, l=0, r=0;
    for (; i < n; ++i) {
        if (s[i] != 'x') ++cur;
        if (cur == tot-1 && !r) r = i+1;
        if (cur == tot) { l = i; break; }
    }
    if (odd) r = i, l = i+1;
    if (check(r-1, l)) printf("%d
", ans);
    else printf("-1
");
    return 0;
}

Code 2.

#include <bits/stdc++.h>
#define maxn 500010
using namespace std;
typedef long long LL;
char s[maxn];
int cnt[256], n;
LL ans;
struct node {
    char ch;
    int cnt;
}a[maxn], b[maxn];
bool check(int i, int j) {
    int cnt1 = 0, cnt2 = 0, tot1 = 0, tot2 = 0;
    for (; i >= 0; --i) {
        if (s[i] == 'x') ++cnt1;
        else a[tot1++] = {s[i],cnt1}, cnt1 = 0;
    }
    for (; j < n; ++j) {
        if (s[j] == 'x') ++cnt2;
        else b[tot2++] = {s[j],cnt2}, cnt2 = 0;
    }
    if (tot1 != tot2) return false;
    ans = 0;
    for (int i = 0; i < tot1; ++i) {
        if (a[i].ch != b[i].ch) return false;
        ans += abs(a[i].cnt-b[i].cnt);
    }
    ans += abs(cnt1-cnt2);
    return true;
}
int main() {
    scanf("%s", s);
    n = strlen(s);
    for (int i = 0; i < n; ++i) ++cnt[s[i]];
    char ch; int num=0;
    for (char i = 'a'; i <= 'z'; ++i) if (i!='x'&&(cnt[i]&1)) ++num, ch = i;
    if (num > 1) { printf("-1
"); return 0; }

    int p;
    if (num == 1) {
        int hf = cnt[ch]/2+1, pst=0;

        int i = 0;
        for (; i < n; ++i) {
            if (s[i] == ch && pst < hf) ++pst;
            if (pst == hf) break;
        }
        if (check(i-1, i+1)) printf("%lld
", ans);
        else printf("-1
");
    }
    else {
        int tot = 0;
        for (char i = 'a'; i <= 'z'; ++i) if (i!='x')tot += cnt[i];
        if (tot==0) { puts("0"); return 0; }
        tot /= 2;
        int i = 0, pst = 0;
        for (; i < n; ++i) {
            if (s[i] != 'x' && pst < tot) ++pst;
            if (pst == tot) break;
        }
        int p = i+1;
        while (p<n && s[p]=='x') ++p;
        if (check(i, p)) printf("%lld
", ans);
        else printf("-1
");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/kkkkahlua/p/7712317.html