作者:甄之恋 | 来源:互联网 | 2024-10-21 08:15
#B.BalancedBreakdown#####1.题目大意:给定一个n,从n中不断分离回文数(翻转后大小相同的数字)问最少需要多少步,输出最少步数以及一种方案(方案不唯一)##
B.Balanced Breakdown
1.题目大意:给定一个n,从n中不断分离回文数(翻转后大小相同的数字)问最少需要多少步,输出最少步数以及一种方案(方案不唯一)
2.解题思路:贪心构造最大的回文数,从数字中减去
3.解题代码:
#include
using namespace std;
typedef long long ll;
ll n, m;
vectorans;
ll get(ll n){
if(n >= 11 && n <= 99) return n / 11 * 11;//如果n在11至99之间则需要两步返回11的倍数和一个余数
string s = to_string(n);//将数字转为字符串处理,方便进行取半操作
string half = s;
reverse(half.begin(), half.end());
if(s == half) return n;//如果本身是一个回文串那么直接返回自身
if(stoll(half) == 1)return n - 1;//特殊的当右半段是以0开头1结尾的数字时,此时只需要两步,一步时取999...9999 另外一步取 1
half = s.substr(0, s.size() + 1 >> 1);//如果上述都不满足则开始处理,首先将n取半(向上取整,奇数长度多取一个)
half = to_string(stoll(half) - 1);//左半端 - 1 对应过去的右半段那么就是最大值
string ans = half;
int st = half.size() - 1 - s.size() % 2;//根据s的长度对新的ans进行赋值,如果是奇数那么就要少赋值一位
for(int i = st; i >= 0; i--){
ans += half[i];
}
return stoll(ans);
}
int main(){
cin >> n;
while(n) {
m = get(n);
ans.push_back(m);
n -= m;
}
cout < for(auto t : ans){
cout < }
return 0;
}