MS 与美食街 2
Description
MS 是 Legendary Grandmaster DiDiDi 的神仙队友,有关他们如何在各种 GP 上捧杯的故事讲上三天三夜也讲不完。
有一天他们在 GP of Zhijiang 捧杯之后,MS 准备去枝江美食街研究一下今晚吃什么。
美食街可以看成一个序列,MS 通过对美食街的顺序遍历,发现美食街一共有 n 个小吃店,每家店的小吃都各具特色。对于第 ii 家小吃店,吃遍它家的小吃需要花费 a^{c[i]} 元,即每家店小吃的费用都是同一个 a 的幂次。
注意到这个性质的 MS 开始思考,如果他想吃遍这个美食街,并且他携带的钱也得是 a 的幂次,那么他最少要携带多少钱。因为答案 a^k 可能很大,你只需要输出 k 即可。
Input
第一行包括两个整数 n, a,保证 1≤n≤50, 2≤a≤109。
第二行包含 n 个整数,第 i 个整数表示 ci (0≤ci≤109)。
Output
输出一行包含一个整数 k,表示最少需要携带 a^k 元。
Sample Input 1
3 10 5 6 3
Sample Output 1
7
Hint
在上述样例中,三家店的小吃分别花费 10^5 元、10^6 元、10^3 元,三者之和为 1101000 元,故 MS 至少需要携带 10^7 元才能满足题目要求。
思路:把c[i]用a进制数来表示,比如a^1表示1,a^5表示10000,2*a^5+3*a^3表示20300,然后一个一个来进行a进制数的转换,最后输出res判定的时候,需要考虑最高位之前是否有数字,如果是1000,则就只要输出3就可以了,然后也需要考虑最高位是否为1,如果不为1,则要输出最高位+1。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef pair<int, int> PII;
int n, a;
vector<int> c;
vector<PII>mi;
bool find(int x)
{
for (int i = 0; i < mi.size(); i++)
{
if (mi[i].first == x)
return true;
}
return false;
}
int main()
{
cin.tie(0);
cin >> n >> a;
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
c.push_back(x);
}
sort(c.begin(), c.end());
for (int i = 0; i < n; i++)
{
int cnt = 1;
while (i != n - 1 && c[i] == c[i + 1])
{
cnt++;
i++;
}
mi.push_back({ c[i],cnt });
//给mi输入第几位并且数的大小
}
for (int j = 0; j < n; j++) // 如果 n 全在同一位,并且 a为1 ,所以最多需要进行 n次进位 我不知道咋优化了。。
{
int len = mi.size();
sort(mi.begin(), mi.end());
for (int i = 0; i < len; i++)
{
if (mi[i].second >= a)
{
int t = mi[i].second / a; // 需要进多少位
mi[i].second %= a; // 当前位数 进完位之后的数
if (find(mi[i].first + 1)) // 看下一位再mi中有没有 有的话就在下一位+t , 没有的话就在末尾插入
mi[i + 1].second += t;
else
mi.push_back({ mi[i].first + 1,t });
}
}
}
sort(mi.begin(), mi.end());
bool flag = false;
for (int i = 0; i < mi.size() - 1; i++)
{
if (mi[i].second != 0)
{
flag = true;
break;
}
}
if (flag || mi[mi.size() - 1].second != 1)
cout << mi[mi.size() - 1].first + 1 << endl;
else
cout << mi[mi.size() - 1].first << endl;
return 0;
}