您的位置:首页 > 其它

Ural 1635. Mnemonics and Palindromes

2016-08-05 14:52 302 查看


1635. Mnemonics and Palindromes

Time limit: 1.0 second

Memory limit: 64 MB

The student Vasechkin was terribly unlucky at his oral examination. Of 42 examination questions, he didn't prepare only the last one, and he was asked exactly that
question. Vasechkin was sitting in front of the professor and couldn't say anything. But the professor was in good mood and gave Vasechkin one last chance to pass the exam. He asked the poor student to name the subject in which the exam was being held. Unfortunately,
Vasechkin couldn't recall the name, though he remembered that in that name there were such words as safety, programs, devices, and, possibly, informatics…

To get ready for the reexamination, Vasechkin decided to learn the name of the subject. To better remember that long string, he decided to decompose it into palindromes
and learn each of the palindromes separately. Of course, the number of palindromes in the decomposition had to be as small as possible.

Input

In the first line there is the name of the subject in which Vasechkin was examined. This is a nonempty line consisting of lowercase English letters. The length
of the line is at most 4000 symbols.

Output

In the first line output the minimal number of palindromes to which the name of the subject can be decomposed. In the second line output palindromes from the optimal
decomposition separated by a space. If several answers are possible, output any of them.

Samples

inputoutput
pasoib

6
p a s o i b

zzzqxx

3
zzz q xx

wasitacatisaw

1
wasitacatisaw

Problem Author: Igor Chevdar
Problem Source: XIII Open USU Championship

Difficulty: 220    Printable
version    Submit solution    Discussion
(35)

My submissions    All
submissions (5582)    All accepted submissions (1624)    Solutions
rating (1322)
题意:
给一个字符串,求最少可以分为多少个回文子串

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define pi acos(-1.0)
#define maxn (4000 + 50)
#define mol 1000000009
#define inf 0x3f3f3f3f
#define Lowbit(x) (x & (-x))
using namespace std;
typedef long long int LLI;

//dp[i]表示从0到i最少有多少回文子串,初始为最大值
//dp[i] = min(dp[j] + 1);
//pre[i]存的是以i结尾的回文子串的首地址(下标)

char str[maxn];
int dp[maxn];
int vis[maxn][maxn];
int pre[maxn];

void handle(int n) {
//vis[i][j]表示从i到j是不是回文串
//依据原理:如果i到j不是回文的,那么i-1到j+1也不是回文的
for(int i = 0; i < n; i ++) {
for(int j = 0;; j ++) {//这是以i为对称轴,左右分别延伸j长度的
if(i - j < 0)   break;
if(i + j >= n)   break;
if(str[i + j] != str[i - j])    break;
vis[i - j][i + j] = true;
}
for(int j = 1;; j ++) {//这是以i和i+1中间为对称轴
if(i - j + 1 < 0)   break;
if(i + j >= n)      break;
if(str[i - j + 1] != str[i + j])    break;
vis[i - j + 1][i + j] = true;
}
}
}
stack > asta;
int main() {
//    freopen("in.txt", "r" , stdin);
//    freopen("out.txt", "w" , stdout);
scanf("%s",str);
int len = strlen(str);
fill(dp,dp + maxn,inf);
fill(pre,pre + maxn,-1);
memset(vis,false,sizeof(vis));
handle(len);
dp[0] = 1;
for(int i = 0; i < len; i ++) {
if(vis[0][i])   dp[i] = 1,pre[i] = 0;
}
for(int i = 0;i < len;i ++){
if(dp[i] == 1)  continue;
for(int j = 0;j < i;j ++){
if(vis[j + 1][i] && dp[i] > dp[j] + 1){
dp[i] = dp[j] + 1;
pre[i] = j + 1;
}
}
}
printf("%d\n",dp[len - 1]);
int p = pre[len - 1],e = len - 1;
while(e != -1 && p != -1){
asta.push(pair(p,e));
e = p - 1;
p = pre[e];
}
while(!asta.empty()){
int x = asta.top().first;
int y = asta.top().second;
asta.pop();
for(int i = x;i <= y;i ++){
printf("%c",str[i]);
}
if(!asta.empty())   printf(" ");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息