1、最大映射
有 n 个字符串,每个字符串都是由 A-J 的大写字符构成。现在你将每个字符映射为一个 0-9 的数字,不同字符映射为不同的数字。这样每个字符串就可以看做一个整数,唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零。现在问你怎样映射字符才能使得这些字符串表示的整数之和最大?
输入描述:
每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n , 接下来有 n 行,每行一个长度不超过 12 且仅包含大写字母 A-J 的字符串。 n 不大于 50,且至少存在一个字符不是任何字符串的首字母。
输出描述:
输出一个数,表示最大和是多少。
输入例子:
2
ABC
BCA
输出例子:
1875
代码如下:
#include<iostream> #include<vector> #include<string> #include<algorithm> #include<numeric> //数值算法 using namespace std; //节点类:每个字符对应一个权重 struct Node { char ch; long long num; Node() {} //默认构造函数 Node(char c, int n) :ch(c), num(n) { } }; //按照权重对节点进行排序 bool cmp(const Node &a, const Node &b) { return a.num < b.num; } //取得每个字符的权重 void getWeight(vector<string> &data, vector<Node> &arr) { for (int i = 0; i < data.size(); ++i) { long long index = 1; for (int j = data[i].size() - 1; j >= 0; --j) { int pos = data[i][j]; arr[pos - ‘A‘].num += index; index *= 10; } } } int main() { int n; while (cin >> n) { string str; //字符串集合 vector<string> data(n); for (int i = 0; i < n; ++i) { cin >> str; data[i] = str; } //节点类集合 vector<Node> arr(10); for (int i = ‘A‘; i <= ‘J‘; ++i) { arr[i - ‘A‘] = Node(i, 0); } //计算每个字符的权重 getWeight(data, arr); //按照权重由小到大进行排序 sort(arr.begin(), arr.end(), cmp); //每个字符是否在字符串首位置出现过(1:出现过) vector<int> flag(10, 0); for (int i = 0; i < n; ++i) { flag[data[i][0] - ‘A‘] = 1; } //在排序数组中,第一个没有在字符串首位置出现的字符的位置 int spec_pos = 0; for (; spec_pos < 10; ++spec_pos) { if (flag[arr[spec_pos].ch - ‘A‘] == 0) break; } Node tmp = arr[spec_pos]; //向后移动一位,把spec_pos位置的元素放在首部 for (int i = spec_pos; i > 0; --i) { arr[i] = arr[i - 1]; } arr[0] = tmp; //将0~9赋值给相应的字符 vector<int> numArr(10); for (int i = 0; i < 10; ++i) { numArr[arr[i].ch - ‘A‘] = i; } //字符串集合转换为整型数集合 vector<long long> num(n); for (int i = 0; i < n; ++i) { long long val = 0; long long index = 1; for (int j = data[i].size() - 1; j >= 0; --j) { val += numArr[data[i][j] - ‘A‘] * index; index *= 10; } num[i] = val; } long long count = 0; //对整型数集合求值 cout << accumulate(num.begin(), num.end(), count) << endl; } return 0; }
时间: 2024-10-10 14:16:56