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