题面:
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.
The first line contains an integer nn (1≤n≤10181≤n≤1018). It is guaranteed that the first (left) digit of the number nn is not a zero.
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.
5071
4
705
1
1241367
-1
In the first example one of the possible sequences of moves is 5071 →→ 5701 →→ 7501 →→ 7510 →→ 7150.
题面描述:
给你一个1到1e18的数,每次你可以将相邻的两个数交换,问你是否能在若干次交换后,使新的数能被25整除。如果能则输出最小的交换次数,否则输出-1。
题目分析:
我们需要发现,25的倍数有一个特性,无论其他数如何变,只要是以00、25、50、75结尾的数,必定是25的倍数。(因为对于这些数,无论前缀为多少,在除以5之后,最后的结尾总是能够为0或5,使得其结果还能被5整除)
发现了这个规律之后,我们只需要贪心的进行比较,将原有的数贪心地分别以上述四个后缀为结尾,判断是否能够通过交换构成,如果能则贪心的选取最小的即可。
而这个题还需要注意的一点前导0的处理,对于前导0的处理,因为每次的交换是相邻的交换的,因此第i位换到第j位只需要移动i-j次。所以如果出现构成00/25/50/75后缀后,出现前导0,我们只需要从第1位到第n-2位不断的寻找第一个非零的数,将此时的下标-1再加进cnt次数中进而跟答案比较即可。
代码:
#include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
string str1,str2;
bool vis=0;
void Get(char a,char b,int n,int &ans){
str2=str1;
int cnt=0;
int tmp=0;
for(int i=n-1;i>=0;i--){//将最后一位置为字符b
if(str2[i]==b){
cnt++;
for(int j=i;j<n-1;j++){
swap(str2[j],str2[j+1]);
tmp++;
}
break;
}
}
for(int i=n-2;i>=0;i--){//将倒数第二位置为字符a
if(str2[i]==a){
cnt++;
for(int j=i;j<n-2;j++){
swap(str2[j],str2[j+1]);
tmp++;
}
break;
}
}
if(cnt==2){//如果能够构成后缀ab
if(str2[0]!='0'){
vis=1;
//cout<<tmp<<endl;
ans=min(ans,tmp);
}//如果有前导0
else{
for(int i=0;i<n-2;i++){
if(str2[i]!='0'){//从第1位到n-2位找到第一个不为0的数
tmp+=i;
vis=1;
ans=min(ans,tmp);
break;
}
}
}
}
}
int main()
{
cin>>str1;
int len=str1.length();
int ans=INF;
//四种情况贪心取最小
Get('0','0',len,ans);
Get('2','5',len,ans);
Get('5','0',len,ans);
Get('7','5',len,ans);
if(vis) cout<<ans<<endl;
else puts("-1");
return 0;
}