招商银行信用卡中心M-Geeker技术竞赛初赛

202 阅读1分钟

招商银行信用卡中心M-Geeker技术竞赛初赛

招商银行信用卡中心M-Geeker技术竞赛初赛2020
考试时间:(北京时间,UTC+08:00)08-03 15:00:00 -- 16:30:00

第一题:编码与倒置

int main()
{
	unordered_map<int, string> um{
		{0,"0000"},{1,"1000"},{2,"0100"},
		{3,"1100"},{4,"0010"},{5,"1010"},
		{6,"0110"},{7,"1110"},{8,"0001"},
		{9,"1001"}
	};
	int n;
	cin >> n;
	while (n--)
	{
		int a;
		cin >> a;
		string str = "";
		while (a)
		{
			str += um[a % 10];
			a /= 10;
		}
		while (str.size() < 12)str += um[0];
		int idx = 0;
		while (idx < str.size() - 1 && str[idx] == '0')idx++;
		cout << str.substr(idx) << endl;
	}
}

第二题:字典序的最小值

n为字符串长度,k为字典中字符个数 思路简述:输出字符串的末尾按照字典序从高到低写入,前面利用'a'和'b'间隔填充。
例如:

n=11, k=7

输出:

abababcdefg
int main()
{
	int n, k;
	cin >> n >> k;
	if (n < k || (n>1 && k==1))
	{
		cout << -1<<endl;
		return 0;
	}
	string str(n,'a');
	int idx = n - 1;
	for (int i = k-1;i>1;i--)
	{
		str[idx--] += i;
	}
	for (int i = 1; i <= idx; i += 2)
	{
		str[i] = 'b';
	}
	cout << str << endl;
	return 0;
}

第三题:分裂的最大乘积和与最小分裂次数

思路简述:如果分裂k次,那么当前有(k+1)个数字,这(k+1)个数字彼此相乘然后求和,就是当前收益。又这(k+1)个数字的和是固定的(为输入s),令这(k+1)个数尽量平均(参考柯西不等式),则得到的和最大。

例如:333分裂四次得到66, 66, 67, 67, 67,当前的收益为这五个数字两两组合的乘积的和(乘法结合律),即44355。

vector<long> breakN(long& val,int N)
{
	long sum = 0;
	vector<long> par(N,val/N);
	sum = par[0] * N;
	int i = 0;
	while (sum++ < val)
	{
		par[i++]++;
	}
	return par;
}

long calProfit(vector<long>& nums)
{
	long res = 0;
	for (int i = 0; i < nums.size() - 1; i++)
	{
		for (int j = i + 1; j < nums.size(); j++)
		{
			res += nums[i] * nums[j];
		}
	}
	return res;
}

int main()
{
	long s, m;
	cin >> s >> m;
    if(s>m)
    {
        cout<<0<<endl;
        return 0;
    }
    if(s<=1)
    {
        cout<<-1<<endl;
        return 0;
    }
	long count = 2;
	long profit = 0;
	while (profit < m && count<=s)
	{
		profit = 0;
		vector<long> par = breakN(s, count++);
		profit = calProfit(par);
	}
	count -= 2;
	if (profit >= m)
		cout << count << endl;
	else
		cout << -1 << endl;
	return 0;
}