-
增量N,
-
从左侧开始扫描,直到找到大于1的数字为止。递增部分数字,然后将其余部分归零。
例如
12 -> 13 -> 1|3 -> 10|0
101 -> 102 -> 10|2 -> 11|0
109 -> 110 -> 110|
111 -> 112 -> 11|2 -> 100|0
198 -> 199 -> 1|99 -> 10|00
1098 -> 1099 -> 10|99 -> 11|00
10203 -> 10204 -> 10|204 -> 11|000
111234 -> 111235 -> 111|235 -> 1000|000
...
证明:
请求的数字必须至少为N + 1,这就是我们递增的原因。我们现在正在寻找一个更大或相等的数字。
让我们将前缀称为开头的0/1数字,后跟后缀。我们必须将后缀的第一位替换为零,并设置较大的前缀。合适的最小前缀是当前前缀加1。而适合的最小后缀是全零。
更新:
我忘记指定前缀必须以二进制数字的形式递增 ,否则会出现禁止的数字。
,
另一种可能性是以下可能性:
-
您从所使用的数据类型支持的最大的十进制数字“ 1111111 ... 1111”开始
该算法假定输入小于此数字;否则,您将不得不使用其他数据类型。
示例:使用long long
时,您要以数字1111111111111111111
开头。
- 然后从左到右处理每个十进制数字:
- 尝试将数字从1更改为0。
- 如果结果仍然大于输入值,请进行更改(将数字更改为0)。
- 否则数字仍为1。
示例
Input = 10103
Start: 111111
Step 1: [1]11111,try [0]11111; 011111 > 10103 => 011111
Step 2: 0[1]1111,try 0[0]1111; 001111 < 10103 => 011111
Step 3: 01[1]111,try 01[0]111; 010111 > 10103 => 010111
Step 4: 010[1]11,try 010[0]11; 010011 < 10103 => 010111
Step 5: 0101[1]1,try 0101[0]1; 010101 < 10103 => 010111
Step 6: 01011[1],try 01011[0]; 010110 > 10103 => 010110
Result: 010110
正确性证明:
在此算法中,我们逐位处理。在每个步骤中,都有其值已知的数字和尚不知道其值的数字。
在每个步骤中,我们探查最左边的未知数字。
我们将该数字设置为“ 0”,并将所有其他未知数字设置为“ 1”。因为要探测的数字是未知数字中的最高位,所以结果数字是最大可能数字,该数字为“ 0”。如果此数字小于或等于输入,则所探查的数字必须为“ 1”。
另一方面,所得到的数字小于要探查的数字为“ 1”的所有可能的数字。如果结果数字大于输入的数字,则该数字必须为“ 0”。
这意味着我们可以在每一步中计算一位。
C代码
(C代码也应在C ++下工作):
long long input;
long long result;
long long digit;
... read in input ...
result = 1111111111111111111ll;
digit = 1000000000000000000ll;
while( digit > 0 )
{
if(result - digit > input)
{
result -= digit;
}
digit /= 10;
}
... print out output ...
,
让我提出一些替代方案。
I。递增。认为它是@YvesDaoust方法的修改。
- 将N增加1
- 以前导零扩展结果
- 从最后一位到第二位
(a)如果小于2,则保留所有内容
(b)否则将其设置为0并增加前导
- 重复步骤3a,b
示例:
1. N = 0 -> 1 -> (0)|(1) -> 1
2. N = 1 -> 2 -> (0)|(2) -> (1)|(0) -> 10
3. N = 101 -> 102 -> (0)|(1)(0)(2) -> (0)|(1)(1)(0) -> (0)|(1)(1)(0) -> (0)|(1)(1)(0) -> 110
4. N = 298 -> 299 -> (0)|(2)(9)(9) -> (0)|(2)(10)(0) -> (0)|(3)(0)(0) -> (1)|(0)(0)(0) -> 1000
您将获得十进制格式的结果。
II。划分。
- 将N增加1
- 将总和设置为0
- 将结果除以10得到div(D)和mod(M)部分
- 检查M
(a)如果M超过1,则增加D
(b)否则将总和增加M * 10 k ,其中k是当前迭代次数(从0开始)
- 重复步骤3,4,直到D为0
示例1:
1. N = 0 -> N = 1
2. sum = 0
3. 1/10 -> D == 0,M == 1 -> sum = sum + 1*10^0 == 1
4. D == 0 -> sum == 1
示例2:
1. N = 1 -> N = 2
2. sum = 0
3. 2/10 -> D == 0,M == 2 -> D = D + 1 == 1
4. 1/10 -> D == 0,M == 1 -> sum = sum + 1*10^1 == 10
5. D == 0,sum == 10
示例3:
1. N = 101 -> N = 102
2. sum = 0
3. 102/10 -> D == 10,M == 2 -> D = D + 1 == 11
4. 11/10 -> D == 1,M == 1 -> sum = sum + 1*10^1 = 10
5. 1/10 -> D == 0,M == 1 -> sum = sum + 1*10^2 == 10 + 100 == 110
6. D == 0,sum == 110
示例4:
1. N = 298 -> N = 299
2. sum = 0
3. 299/10 -> D == 29,M == 9 -> D = D + 1 == 30
4. 30/10 -> D == 3,M == 0 -> sum = sum + 0*10^1 == 0
5. 3/10 -> D == 0,M == 3 -> D = D + 1
6. 1/10 -> D == 0,M == 1 -> sum = sum + 1*10^3 == 1000
7. D == 0,sum == 1000
本文链接:https://www.f2er.com/3104269.html