题目链接

题意

给定字符串\(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. go包的理解

    结论: import时指定的字符串,是相对于$GOPATH的目录路径,告诉了go,要去加载这个目录下所有的包文件(不包括子目录中的文件) 一个目录中所有的源文件(不包括子目录)代表了单独的一个包,这些 ...

  2. 精读《Epitath 源码 - renderProps 新用法》

    1 引言 很高兴这一期的话题是由 epitath 的作者 grsabreu 提供的. 前端发展了 20 多年,随着发展中国家越来越多的互联网从业者涌入,现在前端知识玲琅满足,概念.库也越来越多.虽然内 ...

  3. thinkphp 3.2.3 - Think.class.php 解析

    class Think { public static function start() { // 注册AUTOLOAD方法 spl_autoload_register('Think\Think::a ...

  4. Watchmen CodeForces - 650A

    Watchmen CodeForces - 650A Watchmen are in a danger and Doctor Manhattan together with his friend Da ...

  5. CodeForces:#448 div2 B. XK Segments

    传送门:http://codeforces.com/contest/895/problem/B B. XK Segments time limit per test1 second memory li ...

  6. WPF触控程序开发(四)——MultiTouchVista_-_second_release_-_refresh_2的救赎

    起源 Multitouch是一款可用于Win7模拟触摸屏幕的开源软件(关于它的使用介绍),最后一次更新是在11年5月份,我是13年初开始用的,当时开发了一款类似IPhone相册的图片展示触控程序,就是 ...

  7. 4、CSS基础part-2

    1.background-1 ①设置background-image ②设置background-attachment为fixed 可以声明图像相对于可视区是固定的(fixed),因此不会受到滚动的影 ...

  8. 【Restore IP Addresses 】cpp

    题目: Given a string containing only digits, restore it by returning all possible valid IP address com ...

  9. leetcode 【 Best Time to Buy and Sell Stock II 】python 实现

    题目: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...

  10. [DM8168]Linux下控制GPIO实现LED流水灯

    首先加载驱动模块,应用程序通过调用API实现GPIO控制功能. 驱动程序: /* * fileName: led_gpio.c * just for LED GPIO test * GP1_14 -& ...