最小回文数之和

最小回文数之和

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

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

例如 序列 {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

相关推荐