最小回文数之和

最小回文数之和

题目:
这是一道来自搜狗初试的一道算法题,还算简单

给定一个序列,添加一定的元素使之成为回文数,并且是所有可能中元素之和最小的

例如 序列 {1 2 3} 我们可以添加变换为{3 2 1 2 3} {1 3 2 3 1} {1 2 3 2 1}... 其中最小的为{1 2 3 2 1}累加和为9

example

输入:

[1,2,3]

输出:

9

分析

遍历每个元素以每个元素为中心向两边扩张

代码

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

/*#include "stdafx.h"*/
#include <iostream>
#include <climits>
using namespace std;


/*
@p: 输入的数组
@length:数组长度
@return:最小回文长度
*/
int find_min_sum(int p[],int length){
	unsigned short min = INT_MAX;
	for (int i = 0; i < length; i++)
	{
		unsigned short sum = 0;
		int left=i;
		int right=i;
		//找到以i为中心,左右第一个不等的
		while (--left>=0 && p[i]==p[left]);
		while (++right<length && p[i]==p[right]);
		//加上相等的元素
		sum+=(right-left-1)*p[i];
		//左右寻找并添加元素,使之成为回文,并累加
		while (left>=0 && right<length)
		{
			if(p[left]<p[right]){
				sum+=2*p[left];
				left--;
			}
			else if (p[left]>p[right]){
				sum+=2*p[right];
				right++;
			}
			else
			{
				sum+=2*p[right];
				left--;right++;
				
			}
		}
		//有一方到了边界,把另一方剩余元素,逆序放到另一方,并累加
		for (;right < length; right++)
		{
			sum+=2*p[right];
		}
		for (;left>= 0; left--)
		{
			sum+=2*p[left];
		}
		//找到最小值
		if (sum<min)
		{
			//cout<<sum<<endl;
			min=sum;
		}
	}
	//返回最小值
	return min;

}
void test1(){
	//已经是回文数了
	int a[6]={1,2,3,3,2,1};
	if(12==find_min_sum(a,6)) cout<<"test1 ok"<<endl;
}
void test2(){
	//所有数字不等
	int a[6]={1,2,3,4,5,6};
	if(36==find_min_sum(a,6)) cout<<"test2 ok"<<endl;
}
void test3(){
	//中间有重复元素
	int a[4]={1,3,4,3};
	if(12==find_min_sum(a,4)) cout<<"test3 ok"<<endl;

}

int main()
{
    //测试用例
	test1();
	test2();
	test3();

	return 0;
}


结果:

test1 ok
test2 ok
test3 ok
posted @ 2017-12-28 15:58  DsHale  阅读(392)  评论(0编辑  收藏  举报