字节跳动2017后端工程师实习生笔试题分析及答案

转载文章,原文地址:https://blog.csdn.net/godop/article/details/81952088

有 n 个字符串,每个字符串都是由 A-J 的大写字符构成。现在你将每个字符映射为一个 0-9 的数字,不同字符映射为不同的数字。这样每个字符串就可以看做一个整数,唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零。现在问你怎样映射字符才能使得这些字符串表示的整数之和最大?

输入描述:

每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n , 接下来有 n 行,每行一个长度不超过 12 且仅包含大写字母 A-J 的字符串。 n 不大于 50,且至少存在一个字符不是任何字符串的首字母。

输出描述:

输出一个数,表示最大和是多少。

输入例子1:

2
ABC
BCA

输出例子1:

1875

如题所示:可以根据权值大小来赋予字母的值,例如在这题中:

ABC=100×A+10×B+C
BCA=100×B+10×C+A
则ABC+BCA=110×B+101×A+11×C(根据权值从大到小排序)。

要使和最大,那么权值大的,对应的值就应该越大,B为9, A为8,C为7,可算得结果为:1875。

根据以上方法,可以用一个数组保存对应的权值,进行简单排序,然后根据排序的大小,进行赋值求结果;注意,题目中还要求不能有前导零,我们可以设置一个标识,当每项的第一位,就将其标识为1,表示这是不能为零;当它为数组的最小时,则要将其与前面可以为0的交换位置,例如:

A 100 1
J 11 1
C 10 0
D 9 0
E 8 1
B 7 0
G 6 0
H 5 1
I 4 1
F 3 1

此处的F的标识位为1,表示其不能为0,则需要寻找其前面可以为0的项,很明显G 6 0这项,标识位为0,将G 6 0放到末尾去,变成:(H 5 1 和 I 4 1 这两项都标识位都为1,不能放在尾部)

A 100 1
J 11 1
C 10 0
D 9 0
E 8 1
B 7 0
H 5 1
I 4 1
F 3 1
G 6 0

AC代码:

#include<iostream>
#include<algorithm>
using namespace std;
struct WeightInt
{
    long w;
    int flag;
}wi[10];
int n;
bool compare(WeightInt a, WeightInt b)        //以从小到大的方式排序
{
    return a.w < b.w;
}
int main()
{
    cin>>n;
    string s;
    for(int i = 0; i < n; i++)
    {
        cin >> s;
        long base = 1;
        for(int j = s.size()-1; j >= 0; j--, base *= 10)
        {
            int idx = s[j] - 'A';
            if(j == 0) wi[idx].flag = 1;
            wi[idx].w += base;
        }
    }
    sort(wi, wi+10, compare);
    if(wi[0].flag == 1)
    {
        int k = 0;
        for( ; k < 11; k++)
            if(wi[k].flag == 0)
                break;
        WeightInt tmp = wi[k];
        for(;k>0; k--)
            wi[k] = wi[k-1];
        wi[0] = tmp;
    }
    long sum = 0;
    for(int i = 9; i >= 0; i--)
    {
        sum += wi[i].w*i;
    }
    cout << sum << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Jarvenman/article/details/88945850