Codeforces Round #486 (Div. 3) E. Divisibility by 25

E. Divisibility by 25

能被25整除的充要条件就是末两位是00,25,50,75。如果没有过程中不出现前导0这一限制,显然对每种情况,贪心取尽量低位即可。本题的关键就在于如何满足这个条件,首先有个”显然”的方法:讨论。。。然后会发现情况太多,过于复杂。所以,我们只好从交换本身的性质入手,找找易于实现的写法。注意到我们最多移动3个数字的位置,最终两个最低位的数,可能还有一个非0数作为最高位,而根据交换的性质,可以发现先移动那个数对于最终的结果没有影响,按照题意我们要先移动那个作为最高位的数,那现在既然调换顺序没有影响,不如把那个数留到最后再交换。于是,这道题的做法就出来了:1)贪心模拟,确定最低两位2)贪心模拟,确定最高位3)检查最后两位是否合法。

#include <bits/stdc++.h>
typedef long long ll;
const int inf = 0x3f3f3f3f;
using namespace std;
int n;
char s[22],tmp[22];
int solve(char a, char b) {
    int p=n-1, ans=0;
    for(p;p>=0;--p)if(s[p]==b)break;
    if(p==-1)return inf;
    for(int i=p+1;i<n;++i)swap(s[i],s[i-1]),++ans;
    p=n-2;
    for(p;p>=0;--p)if(s[p]==a)break;
    if(p==-1)return inf;
    for(int i=p+1;i<n-1;++i)swap(s[i],s[i-1]),++ans;
    for(p=0;p<n;++p)if(s[p]!='0')break;
    for(;p>=1;--p)swap(s[p],s[p-1]),++ans;
    if(s[n-2]==a&&s[n-1]==b) return ans;
    return inf;
}
int main() {
    scanf(" %s",s);
    memcpy(tmp,s,sizeof(s));
    n=strlen(s);
    int ans = inf;
    ans = min(ans,solve('7','5'));
    memcpy(s,tmp,sizeof(tmp));
    ans = min(ans,solve('2','5'));
    memcpy(s,tmp,sizeof(tmp));
    ans = min(ans,solve('5','0'));
    memcpy(s,tmp,sizeof(tmp));
    ans = min(ans,solve('0','0'));
    printf("%d\n",(ans==inf)?-1:ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/RRRR-wys/p/9124283.html