这道题是一道还算可以的贪心,我们考虑的贪心思路是
- 把最靠近最后一位的偶数与最后一位交换,反例: 12345应该变为15342,而此时的变化为12354.排除。
- 把位于高位且比最后一位(L-1)的数小的数和最后一位交换, 例如 2455->5352. 但显然这样写的代码是错误的,会存在最后一个数比所有的偶数都小,举个反例 4443->4434而不是3444.也排除。
- 先从高位到低位遍历一遍,找到第一个比最后一位小的偶数即可,如果不存在,就再从后往前遍历一遍,找到最低位的偶数与最后一位交换即可。
(这是正解!) - 记得特判一下全是奇数,没有偶数的情况,直接输出-1即可。
(本人较菜,所以用了字符串转数组,在数组里进行的操作)
for(int i=0;i<l;i++)
{
a[i]=s[i]-'0';//转数字
if(a[i]%2==0)
{
ok=1;//查看是否有偶数
}
}
//大体的操作就是这样,在数组里面做运算就不用考虑忘记删掉'0'的问
//题,但是这样的空间可能会占用的大一些
代码详解:利用flag和ok两个bool变量,一个记录是否有偶数,一个去寻找最高位的偶数,在去利用变量q去存最高位的偶数的下标,便于交换
AC代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#define maxn 100005
#define ll long long
#define itn int
#define INF 1e+9
using namespace std;
string s;//存初始的串
int a[maxn],q;//a[]表示转换后的数字串
bool flag=0,ok=0;
int main()
{
cin>>s;
int l=s.length();
memset(a,0,sizeof(a));
for(int i=0;i<l;i++)
{
a[i]=s[i]-'0';//转数字
if(a[i]%2==0)
{
ok=1;//查看是否有偶数
}
}
for(int i=0;i<l;i++)
{
if(a[i]%2==0&&flag==0&&a[i]<a[l-1])//找到在最高(所有偶数中位置最靠前)位且比最后一位小的偶数
{
flag=1;
q=i;
continue;
}
}
if(ok==0)//全是奇数
{kaoqian
printf("-1\n");
return 0;
}
if(flag==1)
swap(a[q],a[l-1]);
else //不存在比最后一位小的偶数
{
for(int i=l-1;i>=0;i--)//找到最靠后的一位偶数
{
if(a[i]%2==0)
{
swap(a[i],a[l-1]);
break;
}
}
}
for(int i=0;i<l;i++)//正序输出
{
printf("%d",a[i]);
}
}