E - Divisibility by 25(思维)

传送门

大佬

  • 题意
    给你一个整数n(1≤n≤1018,不含前导零),你能够将任意两个相邻位置上的数互换位置,每交换一次算一步,每一次交换过后的数不能有前导零。现在要求以最少的步数使这个数变为25的倍数,输出这个步数。

  • 思路:看上面大佬链接

  • 我的理解:
    举例:
    n = 1153246
    目的明显,即将‘2’‘5’移到最右边。(第一次移动‘5’,第二次移动‘2’)

    观察发现,其实无论‘2’和‘5’谁在前谁在后,每次移动都是为了移动到‘6’后面的第一位。(也即计算‘2’和‘5’相对‘6’的位置,但注意,计算‘2’与‘6’的相对位置前,需要将‘5’删掉,因为‘5’已经移到右边了)

    上述大佬的题解中,之所以删掉‘5’,是为了避免将‘5’移动到‘6’的右边后,计算‘2’与‘6’的相对位置时,由于’5‘的存在而造成误差(’2‘在’5‘的左边时,’5‘占一位,这里好像与上面链接中的矛盾,我觉得是大佬的错了。。。)

    最后对前导零的情况作处理,若剩下的都为0(删除那两个字符后剩下的串),则这种情况不可取,返回inf即可,否则就将第一个不为0的移到最左边。

最后献上我的代码:

#include<cstdio>
#include<queue>
#include<cstdlib>
#include<string.h>
#include<string>
#include<iostream>
#include<cmath>
#include<map>
#include<algorithm>
#define endl "\n"
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
#define ft first
#define sd second
#define pll pair<ll, ll>
#define pii pair<int, int>
#define ll long long int
#define mt(a,b) memset(a, b, sizeof a)
const int inf = 0x3f3f3f3f;
const int INF = 0x7fffffff;
using namespace std;
const int N = 2e5, M = 1e6;

int judge(char a, char b, string s)
{
	int len = s.size();

	int idx2 = s.rfind(b);
	if (idx2 == -1) return inf;
	s.erase(idx2, 1);

	int idx1 = s.rfind(a);
	if (idx1 == -1) return inf;
	s.erase(idx1, 1);

	int cnt = 0;
	while (s[cnt] == '0') cnt++;
	if (cnt && cnt + 2 == len) return inf;//删除a和b后剩字符下全为0 ,注意要判断一下是否存在前导零

	//cout << cnt << "----\n";
	//cout << a << b << " " << cnt + len - 1 - idx2 + len - 2 - idx1 << endl;
	return cnt + (len - 1 - idx2) + (len - 2 - idx1);//len - 1为b未删掉前字符串最右边的索引,len - 2 为删掉后最右边的索引
}
int main()
{
	IOS;
	string s;
	cin >> s;

	int ans = inf;
	ans = min(judge('2', '5', s), ans);
	ans = min(judge('0', '0', s), ans);
	ans = min(judge('7', '5', s), ans);
	ans = min(judge('5', '0', s), ans);

	if (ans == inf) cout << -1 << endl;
	else cout << ans << endl;

	return 0;
}

end

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

to cling

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值