codeforces-988E-Divisibility by 25【模拟?】

codeforces-988E-Divisibility by 25

自认为这是一道好题

题意:给出一个数n (1≤n≤10^18),每次可以交换相邻的两个数,问你最少交换几次可以被25整除,不允许有前导零

一个数想要被25整除,尾数就必须是25 50 75 00 其中的一种,具体为什么自己研究,如果不是,你来找我

那就好办了,比如说是要找25,那么为了保证交换次数最小,就应该从后往前找,找到5的位置是a,2的位置是b, 那么应该在前面的2就应该交换 l-2-b次,在后面的应该交换 l-1-a次,如果不明白怎么来的手动模拟一下

找位置的时候可以用string 的rfind函数,是可以从后往前找的!!

 还有两个要注意的地方,在找到一个数之后要把它删掉,因为这个地方你可能交换之后他第一位就变成0了,如果交换后存在前导0,那么在答案中加上第一个不是0的位置就可以了

/*傻孩子之前直接从后往前遍历找'0','2''5''7'的位置然后计算,于是写了个巨长巨长的代码,也不是不可以,但是要考虑(比如465243,这样,你不仅要算l-2-b+l-1-a,还要再加1,因为你把2换到正确的位置之后5还要过去就把2挤到前面去了,然后43652比如这样就不用考虑之前的情况,还要考虑前导零等等等等一系列的情况,孩子改不起了,哭死,于是换了方法,牢骚释放完毕,总之想要写大模拟? 慎重*/

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int N=1e6+9;
 5 const int inf=0x3f3f3f3f;
 6 string s;
 7 int solve(char x,char y)
 8 {
 9     string now=s;
10     int l=now.size();//要提前取字符串的长度,我删了之后再取,wa了几遍都没有发现
11     int a=now.rfind(y);
12     if(a!=-1) now.erase(a,1);
13     int b=now.rfind(x);
14     if(b!=-1) now.erase(b,1);
15     if(a==-1||b==-1) return inf;
16     int cnt=0;
17     for(int i=0;i<l;i++)
18     {
19         if(now[i]=='0') cnt++;
20         else break;
21     }
22 //    printf("%d %d %d cnt a b
",cnt,a,b);
23     return l-2-a+l-1-b+cnt;
24 }
25 int main()
26 {
27     cin>>s;
28     int l=s.size();
29     int _50=solve('5','0');
30     int _00=solve('0','0');
31     int _25=solve('2','5');
32     int _75=solve('7','5');
33 //    printf("%d %d %d %d
",_00,_50,_25,_75);
34     int ans=min(min(min(_50,_00),_25),_75);
35     if(ans==inf) printf("-1
");
36     else printf("%d
",ans);
37     return 0;
38 }
原文地址:https://www.cnblogs.com/YangKun-/p/12567431.html