8633 回文划分

8633 回文划分

该题有题解

时间限制:1000MS 内存限制:1000K
提交次数:169 通过次数:63

题型: 编程题 语言: C++;C
Description

我们说一个字符串是回文串,那么意味着这个串从两边读起来的字母都是一样的。例如racecar是回文串,

然而fastcar则不是。
对一个串的划分意思是将一个串划分为若干个部分。例如,racecar可以划分为race 和car两部分。给出
一个串,要把这个串划分为若干个回文串,那么至少要把这个串划分为多少部分?
例如
'racecar’已经是回文串,划分为1 个部分即可(这个部分就是racecar)。
‘fastcar’ 需要被划分为七个部分 (‘f’, ‘a’, ‘s’, ‘t’, ‘c’, ‘a’, ‘r’)。根据回文串的定义,单个字母也是回文串。
‘aaadbccb’ 分成可以被分为三个回文串 (‘aaa’, ‘d’, ‘bccb’)。找不到更少的划分方法。

输入格式

输入的第一行是数字T,表示输入文件含有T个CASE。之后有T行,每行有一个长度不大于1000的字
符串,全部由小写字母组成,中间没有空格。

输出格式

对于每个CASE,输出一个数字,表示对该字符串的回文串最小划分。

输入样例

3
racecar
fastcar
aaadbccb

输出样例

1
7
3

提示

来源
PKKJ @ 07 GIS 1

#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<iostream>
#include<vector>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
#include<cmath>

//dp数组  dp[i]含义是i以前的最小回文串数
int dp[1005];

//检查数组a中 bg到end是否为回文串
int check(char a[], int bg, int end) {
	//双指针比对
	for (; bg < end; bg++, end--) {
		//如果不同返回0
		if (a[bg] != a[end])return 0;
	}
	//回文串返回1
	return 1;
}

int main(void) {
	char a[1005];
	int T;
	cin >> T;
	//多case
	while (T--) {
		//从a+1开始
		cin >> (a + 1);
		//字符串长度
		int size = strlen(a + 1);
		//遍历字符串数组
		for (int i = 1; i <= size; i++) {
			//先令当前dp[i]为上一格dp[i-1]+1  即i位不能和前面组成回文串的情况   
			dp[i] = dp[i - 1] + 1;
			//定义j从1往后直到i 开始遍历  查j到i是否为字符串
			for (int j = 1; j < i; j++) {
				//如果为字符串
				if (check(a, j, i)) {
					//再比较当前dp[i]是否比 dp[j-1]+1   大
					//dp[j-1]+1含义: dp[j-1](字符串j以前的dp最小值) +1(j到i组成回文串时j到i即为1)
					//如果比原来的大就赋值
					dp[i] = min(dp[j - 1] + 1, dp[i]);
					//不能直接赋值第一个dp[j-1]就退出
					//要比较两者大小
					//abbaa就是一个例子
				}
			}
		}
		//最后输出dp[len]的值即为最小值
		cout << dp[size]<<endl;
	}
	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 答1: 算法步骤: 1. 将字符向量的长度除以2,得到中间位置mid。 2. 将字符向量的前一半字符依次入栈。 3. 从mid位置开始,依次比较字符向量的后一半字符和栈顶字符是否相同,如果不同则不是,返false。 4. 如果比较完所有字符都相同,则是,返true。 代码实现: bool isPalindrome(string s) { int n = s.size(); int mid = n / 2; stack<char> st; for (int i = ; i < mid; i++) { st.push(s[i]); } for (int i = mid + n % 2; i < n; i++) { if (s[i] != st.top()) { return false; } st.pop(); } return true; } ### 答2: 算法如下: 1. 首先将给定的字符向量(字符串)划分为两半,判断长度为奇数还是偶数,分别处理。 - 如果长度为奇数,将中间的字符单独作为字符串的中间部分。 - 如果长度为偶数,没有中间字符。 2. 将前一半的字符依次入栈。 3. 遍历后一半的字符,与栈顶字符进行比较。 - 如果相等,继续比较下一个字符。 - 如果不相等,说明不是,返false。 4. 如果后一半字符遍历完毕,且栈已空,则给定的字符向量是,返true;否则,不是,返false。 ### 答3: 是一种十分有趣的字符序列,通过这种序列的正读和反读都能得到相同的结果。这个问题中,要求我们设计一个算法来判定给定的字符向量是否为。 根据提示,我们可以利用栈的特性来解决这个问题。具体的操作步骤如下: 1. 首先,将字符向量的长度除以2,并取整得到half_length。 2. 创建一个空的栈。 3. 将字符向量的前半部分的字符依次入栈,入栈的范围是从索引0到索引half_length-1。 4. 判断字符向量的长度是奇数还是偶数。如果是奇数,则从索引half_length+1开始遍历字符向量,跳过中间的字符。 5. 从索引half_length开始遍历字符向量的后半部分。对于每个字符,都与栈顶的字符进行比较。 6. 如果字符相同,则继续遍历,并弹出栈顶的字符。 7. 如果字符不同,则说明不是,返False。 8. 如果遍历结束后,栈为空,则说明是,返True。否则,返False。 这个算法的时间复杂度是O(n),其中n是字符向量的长度。空间复杂度是O(n/2),即入栈的字符个数。 例如,对于字符向量"abba",根据以上算法,会将"a"和"b"依次入栈,然后和字符向量的后半部分进行比较。因为字符向量是,所以栈最终为空,返True。 但是对于字符向量"good",它不是,所以在比较过程中会出现字符不同的情况,返False。 通过这个算法,我们可以方便地判断任意给定的字符向量是否为
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值