题意:给你一个数字n(n≤1e18)n(n≤1e18),你每次可以交换他的相邻的两位上的数字,使得这个整数变为整除25的数字的最小步数为多少?如果不能输出-1。
思路:整除25,那么末尾两位为:00,25,50,75时均可以,模拟每种情况,求一个最小值就好。
#include <bits/stdc++.h>
using namespace std;
const int INF = 1000000007;
int ans;
string str;
void solve(char a, char b)
{
string s = str;
int cnt1 = s.rfind(a), cnt2 = s.rfind(b);
if (a == '0' && b == '0') cnt1 = s.rfind(a, cnt1-1);
if (cnt1 == string::npos || cnt2 == string::npos)
return ;
int cnt = 0;
//对于ab的情况,我们先把b移动到最后一位,然后把a移动到倒数第二位
//如果b在a前面,我们先把b看作a,a看作b,移动到最后两位后,交换ba即可
if (cnt1 > cnt2) cnt++, swap(cnt1, cnt2);
for (int i = cnt2; i+1 < s.size(); i++) cnt++, swap(s[i], s[i+1]);
for (int i = cnt1; i+1 < s.size()-1; i++) cnt++, swap(s[i], s[i+1]);
//如果操作完以后第一位为'0'了,那么我们找到第一个不为0的数字,把他交换到第一位即可
cnt += find_if(s.begin(), s.end(), [](char c){ return c != '0'; }) - s.begin();
ans = min(ans, cnt);
}
int main()
{
cin >> str;
ans = INF;
solve('0', '0');
solve('2', '5');
solve('5', '0');
solve('7', '5');
if (ans == INF) ans = -1;
printf("%d\n", ans);
return 0;
}
/*
507
52231
50267
*/
本文介绍了一种算法,该算法通过模拟交换数字字符串中相邻数字的位置来寻找将任意长整数变成25的倍数所需的最少步骤。文章详细解释了如何针对不同的目标结尾(如00、25、50、75)进行最优操作,并给出了具体的实现代码。
1498

被折叠的 条评论
为什么被折叠?



