题目链接

题意

给定字符串\(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. Linux NFS服务器的安装与配置详解

    一.NFS服务简介 NFS是Network File System(网络文件系统).主要功能是通过网络让不同的服务器之间可以共享文件或者目录.NFS客户端一般是应用服务器(比如web,负载均衡等),可 ...

  2. 与SVN相关的程序的调试问题【转】

    解决eclipse中出现Resource is out of sync with the file system问题. 分析:有时候因为时间紧迫的原因,所以就没去管它,今天再次遇到它,实在看着不爽,所 ...

  3. Olympic Class Ships【奥林匹克级邮轮】

    Olympic Class Ships You probably know about the Titanic, but it was actually just noe of three state ...

  4. Codeforces Round #464 (Div. 2) E. Maximize!

    题目链接:http://codeforces.com/contest/939/problem/E E. Maximize! time limit per test3 seconds memory li ...

  5. SJTU 1077 加分二叉树

    http://acm.sjtu.edu.cn/OnlineJudge/problem/1077 题意: 设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3…,n为节点 ...

  6. 面试常问 Java基础 冒泡排序

    冒泡排序就是对一个数组进行排序. 用双层for循环就可以解决. 第一层,决定排序的次数. n个数,进行n-1次排序就行了. 第二层,把相邻的两个数比较,谁小,放到后面和下一个数字比较,谁小谁放到后面, ...

  7. 当我们在讨论CQRS时,我们在讨论些神马?

    当我写下这个标题的时候,我就有些后悔了,题目有点大,不太好控制.但我还是打算尝试一下,通过这篇内容来说清楚CQRS模式,以及和这个模式关联的其它东西.希望我能说得清楚,你能看得明白,如果觉得不错,右下 ...

  8. loj6387 「THUPC2018」绿绿与串串 / String

    还是很好做的,大致就是manacher,每个位置为中心的最长回文串要是能抵到最右边就合法,要是能抵到最左边,那这个点的是否合法取决于以这个点为中心的最长回文串的右端点是否合法. #include &l ...

  9. Java JVM 内存空间解析

    运行时数据区: 运行时数据区主要分五块,分别是Method Area , VM Stack , Native Method Stack , Heap , program Counter Registe ...

  10. OpenStack之Glance源码简析

    Glance简介 OpenStack镜像服务器是一套虚拟机镜像发现.注册.检索. glance架构图: Glance源码结构: glance/api:主要负责接收响应镜像管理命令的Restful请求, ...