题目链接

题意

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

思路

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

\(cnt\geq1\)

显然无解

\(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\n", ans);
else printf("-1\n");
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\n"); 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\n", ans);
else printf("-1\n");
}
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\n", ans);
else printf("-1\n");
}
return 0;
}

Atcoder CODE FESTIVAL 2017 qual C C - Inserting 'x' 回文串的更多相关文章

  1. Atcoder CODE FESTIVAL 2017 qual C D - Yet Another Palindrome Partitioning 回文串划分

    题目链接 题意 给定一个字符串(长度\(\leq 2e5\)),将其划分成尽量少的段,使得每段内重新排列后可以成为一个回文串. 题解 分析 每段内重新排列后是一个回文串\(\rightarrow\)该 ...

  2. 题解【AtCoder - CODE FESTIVAL 2017 qual B - D - 101 to 010】

    题目:https://atcoder.jp/contests/code-festival-2017-qualb/tasks/code_festival_2017_qualb_d 题意:给一个 01 串 ...

  3. Atcoder CODE FESTIVAL 2017 qual B D - 101 to 010 dp

    题目链接 题意 对于一个\(01\)串,如果其中存在子串\(101\),则可以将它变成\(010\). 问最多能进行多少次这样的操作. 思路 官方题解 转化 倒过来考虑. 考虑,最终得到的串中的\(' ...

  4. 【题解】Popping Balls AtCoder Code Festival 2017 qual B E 组合计数

    蒟蒻__stdcall终于更新博客辣~ 一下午+一晚上=一道计数题QAQ 为什么计数题都这么玄学啊QAQ Prelude 题目链接:这里是传送门= ̄ω ̄= 下面我将分几个步骤讲一下这个题的做法,大家不 ...

  5. atcoder/CODE FESTIVAL 2017 qual B/B(dfs染色判断是否为二分图)

    题目链接:http://code-festival-2017-qualb.contest.atcoder.jp/tasks/code_festival_2017_qualb_c 题意:给出一个含 n ...

  6. Atcoder CODE FESTIVAL 2017 qual B E - Popping Balls 组合计数

    题目链接 题意 \(A+B\)个球排成一行,左边\(A\)个为红球,右边\(B\)个为蓝球. 最开始可以选择两个数\(s,t\),每次操作可以取左起第\(1\)或\(s\)或\(t\)个球.问有多少种 ...

  7. Atcoder CODE FESTIVAL 2017 qual B C - 3 Steps 二分图

    题目链接 题意 给定一个无向图,\(n\)个点,\(m\)条边(\(n,m\leq 1e5\)). 重复如下操作: 选择相异的两点u,v满足从点u出发走三条边恰好能到达点v.在这样的u,v点对之间添一 ...

  8. [Atcoder Code Festival 2017 Qual A Problem D]Four Coloring

    题目大意:给一个\(n\times m\)的棋盘染四种颜色,要求曼哈顿距离为\\(d\\)的两个点颜色不同.解题思路:把棋盘旋转45°,则\((x,y)<-(x+y,x-y)\).这样就变成了以 ...

  9. [Atcoder Code Festival 2017 Qual B Problem F]Largest Smallest Cyclic Shift

    题目大意:给你\(A\)个a,\(B\)个b,\(C\)个c,要你构造一个字符串,使它的最小循环表示法最大.求这个表示法.解题思路:不知道怎么证,但把a.b.c当做单独的字符串扔进容器,每次把字典序最 ...

随机推荐

  1. Ubuntu 下使用虚拟串口进行开发测试

    1. python 工具 #coding = utf-8 import pty import os import select def mkpty(): master1, slave = pty.op ...

  2. 正则表达式-基础知识Review

    正则表达式(Regular Expression)是计算机科学的一个概念. 正则表达式使用单个字符窜来描述.匹配一系列符合某个句法规则的字符窜. 在很多文本编辑器里, 正则表达式通常用来被检索替换哪些 ...

  3. 简述在php中 = 、==、 === 的区别(简述在php中 等于 、双等于、 三等于 的区别)

    = 是赋值:就是说给一个变量赋值 == 是轻量级的比较运算,只看值不看类型 === 是重量级的比较运算,既看值,也看类型,要绝对相等才会为true

  4. PHP 二维数组某个字段进行排序

    /** * @param $arrUsers * @return mixed *二维数组某个字段进行排序 */ function quick_sort($arrUsers) { $sort = arr ...

  5. JZOJ 5459. 【NOIP2017提高A组冲刺11.7】密室

    5459. [NOIP2017提高A组冲刺11.7]密室 (File IO): input:room.in output:room.out Time Limits: 1000 ms  Memory L ...

  6. 13.VUE学习之控制行内样式

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  7. while循环中continue和break的区别

    除了满足while条件外,还有两种方法可以终止循环,它们分别是break和continue.它们唯一的区别是break跳出整个循环,直接执行下面的代码了;而continue是终止当次循环,不执行下面的 ...

  8. C++构造函数使用的多种方法

    // classes and uniform initialization #include <iostream> using namespace std; class Circle { ...

  9. Docker从零到实践过程中的坑

    欢迎指正: Centos7 下的ulimit在Docker中的坑 http://www.dockone.io/article/522 僵尸容器:Docker 中的孤儿进程 https://yq.ali ...

  10. Java面向对象---方法的创建与重载

    方法的创建 方法就是可重复调用的代码段. 定义: 访问修饰符 返回值类型 方法名(参数){ 方法主体 } 返回值类型:void(无返回值):基本数据类型:应用数据类型:类对象等. 方法名的命名规则:第 ...