最小回文数之和
最小回文数之和
题目:
这是一道来自搜狗初试的一道算法题,还算简单
给定一个序列,添加一定的元素使之成为回文数,并且是所有可能中元素之和最小的
例如 序列 {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
                    
                
                
            
        
浙公网安备 33010602011771号