原题题号:1534
我们这样定义lazier数,这种数的两个相邻的数位不相同,例如123,12,10就是lazier数,而11,112,122,100等不是lazier数(因为里面出现了两个相邻的数位一样)。
师给小明布置了一个作业,作业是要小明找出一个大于等于一个正整数n且是最小的lazier数,如果你是小明,你怎么做?
输入包括多行,每行一个整数n(0<n<=2*10^9)。
对应每一个数n,输出对应的lazier数,占一行。
1
2
10
11
2000000000
1
2
10
12
2010101010
这题要巧妙的使用STL,能大大降低难度与代码量。
先读入整数,随后使用to_string()
转化为string
方便处理。由于题目要求输出大于等于n
且最小的数,因此我们只需要从左往右检查,有无相邻的数字相同,如果有,则把相邻数字中后面的数字+1,再后面的数字设置为01循环,就能保证输出的数字是最小的,但这里必须注意,如果将数字+1后发生了进位怎么办(9+1),如果进位后又出现重复的数字怎么办(如899->900),如果发生连续进位怎么办?
这里有一个简单的办法,从左至右检查字符串,若发现重复相邻字符,从重复处截断,把前面的字符串转回整形(使用atoi()
函数)并+1,再转回字符串,合上(使用append()
追加字符串),将后面的数字设为01循环,若发生进位,则再运行一次检查。代码如下:
#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
string bump(string nums, int index)
{
return to_string(atoi(nums.substr(0, index + 1).c_str()) + 1).append(nums.substr(index + 1));
}
int lazier(int num)
{
string nums = to_string(num);
int bumped = 0;
int cnt;
do
{
cnt = 0;
bool flag;
for (int i = 0; i < nums.length() - 1; i++)
{
flag = false;
while (nums[i] == nums[i + 1])
{
++cnt;
flag = true;
nums = bump(nums, i + 1);
}
if (flag)
{
bumped = i + 1;
break;
}
}
if (bumped)
{
for (int i = bumped + 1; i < nums.length(); i++)
{
nums[i] = nums[i - 1] == '0' ? '1' : '0';
}
}
}while (cnt);
return atoi(nums.c_str());
}
int main()
{
int num;
while (~scanf("%d", &num))
{
printf("%d\n", lazier(num));
}
//system("pause");
return 0;
}
本文作者:TTQ
本文链接:https://blog.ponder.fun/archives/24.html
最后修改时间:2020-02-09 13:01:22
本站未注明转载的文章均为原创,并采用 CC BY-NC-SA 4.0 授权协议,转载请注明来源,谢谢!