c++实现求解回文序列问题

【问题描述】如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如:{1, 2, 1}, {15, 78, 78, 15} , {112} 是回文序列, {1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11} 不是回文序列。现在给出一个数字序列,允许使用一种转换操作:选择任意两个相邻的数,然后从序列移除这两个数,并用这两个数字的和插入到这两个数之前的位置(只插入一个和)。
对于所给序列要求出最少需要多少次操作可以将其变成回文序列。
输入描述:输入为两行,第一行为序列长度n ( 1 ≤ n ≤ 50),第二行为序列中的n个整数item[i] (1 ≤ iteam[i] ≤ 1000),以空格分隔。
输出描述:输出一个数,表示最少需要的转换次数
输入样例:

4
1 1 1 3

输出样例:

2

判断序列中第一个元素和最后一个元素是否相同,若相同把这两个元素删除,否则把小的一方和它临近的元素相加保存在其中一个位置并把另一个位置删除,同时转换次数加1,直到序列中元素个数为0。实现方式如下:

#include<vector>
#include<iostream>
using namespace std;

//非递归实现方式
int func(vector<int> v)
{
	int k = 0;
	while(!v.empty())
	{
		int len = v.size();
		if(len == 1)
			break;
		if(v[0] == v[len-1])
		{
			v.erase(v.begin());
			v.erase(v.end()-1);
		}
		else if(v[0] < v[len-1])
		{
			v[1] = v[0] + v[1];
			v.erase(v.begin());
			k++;
		}
		else
		{
			v[len-2] += v[len-1];
			v.erase(v.end()-1);
			k++;
		}
	}
	return k;
}

//递归实现方式
int func1(vector<int> v)
{
	int k = 0,len = v.size();
	if(len <= 1)
		return k;
	if(v[0] == v[len-1])
	{
		v.erase(v.begin());
		v.erase(v.end()-1);
	}
	else if(v[0] < v[len-1])
	{
		v[1] += v[0];
		v.erase(v.begin());
		k++;
		k += func1(v);
	}
	else
	{
		v[len-2] += v[len-1];
		v.erase(v.end()-1);
		k++;
		k += func1(v);
	}
	return k;
}

int main()
{
	int n,x;
	cin>>n;
	vector<int> v;
	for(int i=0;i<n;i++)
	{
		cin>>x;
		v.push_back(x);
	}
	cout<<func(v);
	
	int k = 0;
	cout<<"\n"<<func1(v);
}

测试结果如下:
在这里插入图片描述
在这里插入图片描述

原创文章 14 获赞 16 访问量 6875

猜你喜欢

转载自blog.csdn.net/qq_37638909/article/details/82962113
今日推荐