Divisibility by 25 CodeForces - 988E (技巧的暴力)

You are given an integer nn from 11 to 10181018 without leading zeroes.

In one move you can swap any two adjacent digits in the given number in such a way that the resulting number will not contain leading zeroes. In other words, after each move the number you have cannot contain any leading zeroes.

What is the minimum number of moves you have to make to obtain a number that is divisible by 2525? Print -1 if it is impossible to obtain a number that is divisible by 2525.

Input

The first line contains an integer nn (1n10181≤n≤1018). It is guaranteed that the first (left) digit of the number nn is not a zero.

Output

If it is impossible to obtain a number that is divisible by 2525, print -1. Otherwise print the minimum number of moves required to obtain such number.

Note that you can swap only adjacent digits in the given number.

Examples

Input
5071
Output
4
Input
705
Output
1
Input
1241367
Output
-1

Note

In the first example one of the possible sequences of moves is 5071 → 5701 → 7501 → 7510 → 7150.

 

题意:

给你一个整数,你可以交换这个整数中的相邻的数位,但交换后的数不能有前导0,请你输出最小的交换次数,使之可以被25整除。

思路:

我们应该知道,>1且可以被25整除的数,后两位一定是00,25,50,75,这四个整数。

那么我们先通过记录这个数n的每一位数的数次,来判断是否是输出-1,

如果出现过2次0,或者1次2一次5,或者一次5一次0,一次7一次5都可以确定一定可以交换出想要的数。否则就是-1.

确定一定可以交换出想要的数后,我们就要想法记录出最小的移动次数。

我们可以知道,如果我们想要最后两位是50,那么我们要把一个数字0移动到最后一位,我们想移动次数最小,那么一定是选择移动最靠右边的那个0,5一定是最靠右的5.其他借此类推。

我们怎么记录移动的次数呢?

我们用STL中的string类型中的rfind函数(从右开始查找)

然后如果想找的字符的下标是i,那么需要移动len-i-1次,len是数组的当前长度。

然后把这个字符从string中删除掉,(消除对下一个字符的影响)。

然后另外一个字符同理。

我们要注意移动的结果可能会有前导0的,那么我们只需要记录有多少个前导0,就可以通过移动多少次来把签到0后面的字符移动到第一位。

取多个值中的最小值就是ans。

 

细节见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
inline void getInt(int* p);
const int maxn=1000010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
string s,t;
int cnt[maxn];
int len;
int check(string s,char a,char b)
{
    int res=0;
    if(s.rfind(a)!=-1)
    {
        int id=s.rfind(a);
        res+=len-id-1;
        s.erase(s.rfind(a),1);
        if(s.rfind(b)!=-1)
        {
            id=s.rfind(b);
            res+=len-id-2;
            s.erase(s.rfind(b),1);
            while(s[0]=='0')
            {
                res++;
                s.erase(0,1);
            }
            return res;
        }else
        {
            return inf;
        }
    }else
    {
        return inf;
    }
}
int main()
{
    //freopen("D:\\common_text\\code_stream\\in.txt","r",stdin);
    //freopen("D:\\common_text\\code_stream\\out.txt","w",stdout);
    //gbtb;
    cin>>s;
    t=s;
    len=s.length();
    rep(i,0,len)
    {
        cnt[s[i]]++;
    }
    if((cnt['0']>=2)||(cnt['2']>=1&&cnt['5']>=1)||(cnt['5']>=1&&cnt['0']>=1)||(cnt['7']>=1&&cnt['5']>=1))
    {
        int ans=inf;
        ans=min(ans,check(t,'0','0'));
        ans=min(ans,check(t,'5','2'));
        ans=min(ans,check(t,'0','5'));
        ans=min(ans,check(t,'5','7'));
        cout<<ans<<endl;
    }else
    {
        cout<<-1<<endl;
    }
    return 0;
}

inline void getInt(int* p) {
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    }
    else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}

 

转载于:https://www.cnblogs.com/qieqiemin/p/10759992.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值