TopCoder SRM616 ColorfulCoins 题解
题意
给一套货币,保证任意两种货币存在倍数关系且颜色互不相同。已知货币的币值集合,每次可以询问一个金额,给出货币张数最小的表示方案。问最小的询问次数,使得通过已知信息可以对应货币面值和颜色。
分析
最大的面值问一个
将货币之间的倍数关系看做一个进制关系。每次询问一个金额就是询问一个各个位置进制不同的数。既然面值集合已知,则任何询问我们自己已经知道拆分的结果,可能混淆的只是每次询问个数都相同的不同颜色。这样问题转化为如何通过有限次询问将所有货币在所有轮贡献的集合互不相同。一个细节是全为
这时问题已经与货币面值无关,不妨将货币的进制排序。
假设有两次询问,第一行表示该位置的进制,纵列表示填的数。举例如下:
2 | 2 | 2 | 3 | 3 | 3 | 3 | 3 | 3 |
---|---|---|---|---|---|---|---|---|
0 | 1 | 1 | 0 | 1 | 1 | 2 | 2 | 2 |
1 | 0 | 1 | 2 | 1 | 2 | 0 | 1 | 2 |
注意看第三列,此时的二进制已经没有可用的数字集合。如果再加一个二进制的列就不够了,需要多加一行。可知全为
进制不相同的情况怎么处理?注意到为保证合法,二进制的区间我们只用了
实现上,只有
void solve() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i < n; i++) b[i] = a[i + 1] / a[i];
sort(b + 1, b + n);
for (int i = 1; i < n; i++)
if(b[i] != b[i + 1])
ans = max(ans, lg(b[i], i+1)); // log i+1 base b_i
cout << ans << endl;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】