我们有一个数字N,问题是找到最小的偶数E,使得E> N和N中的数字相同。 N中的数字可能很大。
例如
我通过对数字的数字进行所有排列来蛮力地完成它。我在想是否有更好的方法呢?代码会更好。
感谢。
答案 0 :(得分:2)
您可以使用以下策略查找下一个排列:
让我们说number = 12344875
要找到更大的下一个排列,从右边开始,找到第一个数字小于前一个数字。
在这种情况下:数字= 1234 4 875,这是4。
现在你从4向右移动开始,找到那里最小的数字。 这是5 - > 87的 5 即可。现在交换这两个数字,得到1234 5 87 4 。
交换后,按升序排序5之后的数字。 12345 874 - > 12345的 784 即可。 这种策略总会导致下一个更大的排列,只有这样才能得到均匀和不均匀的数字。
因此,为了找到下一个偶数排列,您需要稍微改变一下。 如果在最后一步中你有一个偶数,则将该部分置换为偶数。
否则从右边再次开始。找到第一个偶数,右边有一个更大的数字。例如,数字= 123 4 75531。 现在用右边的最小数字交换,大于 4 。 导致以下123 5 75 4 31。
从此处加上偶数 4 并将数字放在其间 交换的数字按升序排列,1235 7531 4 - > 1235的 1357 强> 4。
对于这种情况,你有以下号码136531.右边没有数字更大的偶数。所以你看下一个号码, 并且看看是否右边有一个更大的数字(但不是第一个偶数)。这里是1 3 6531 - > 136 5 31所以交换它们并将偶数放在后面并最终按升序排列。 136531 - > 1 5 6 3 31 - > 15331 6 - > 15133的 6 强>
当数字按降序排列时没有解决方案(例如97654)。但是在有1个偶数的情况下,右边没有更高的数字。并且偶数的左边数字在它们的右边没有数字(例如97 6 173)。
在进行这种解释时,我意识到,对于偶数而言,这会变得更加复杂。我试着改善以后的答案。
我希望这很有用。 干杯
答案 1 :(得分:0)
找到最右边的数字i
,其右侧有一个更高的数字j
,其中j
不是其右边的最高偶数,{{1} }。选择最小的e
,切换j
和i
,将j
作为最右边的数字,然后排序(升序)数字{{1}右侧的数字}(不包括e
)。
答案 2 :(得分:0)
例如-输入数字- 21856521 ,运行第一步将产生- 21861255 (奇数),因此我们再次在 21861255 上运行步骤1产生 21861525 (再次为奇数),再次运行将产生 21861552
PS:C ++代码:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main(){
string s;cin>>s;
int n = s.length();
while(true){
int idx = -1;
for(int i=n-2;i>=0;--i){
if(s[i]<s[i+1]){
idx = i;
break;
}
}
if(idx==-1){
cout<<-1<<endl;
break;
}
int swapidx = -1;
for(int i=n-1;i>=idx+1;--i){
if(s[i]>s[idx]){
swapidx = i;
break;
}
}
swap(s[idx],s[swapidx]);
//swapidx will never remain -1 bcz. we will surely find an element greater than s[idx](the right next element to idx is greater than s[idx])
sort(s.begin()+idx+1,s.end());
if((s[n-1]-'0')%2==0){
cout<<s<<endl;
break;
}
}
return 0;
}