ztr loves lucky numbers
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1022 Accepted Submission(s): 429
Problem Description
ztr loves lucky numbers. Everybody knows that positive integers are lucky if their decimal representation doesn't contain digits other than 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not.
Lucky number is super lucky if it's decimal representation contains equal amount of digits 4 and 7. For example, numbers 47, 7744, 474477 are super lucky and 4, 744, 467 are not.
One day ztr came across a positive integer n. Help him to find the least super lucky number which is not less than n.
Lucky number is super lucky if it's decimal representation contains equal amount of digits 4 and 7. For example, numbers 47, 7744, 474477 are super lucky and 4, 744, 467 are not.
One day ztr came across a positive integer n. Help him to find the least super lucky number which is not less than n.
Input
There are T
(1≤n≤105)
cases
For each cases:
The only line contains a positive integer n(1≤n≤1018) . This number doesn't have leading zeroes.
For each cases:
The only line contains a positive integer n(1≤n≤1018) . This number doesn't have leading zeroes.
Output
For each cases
Output the answer
Output the answer
Sample Input
2 4500 47
Sample Output
4747 47
Source
解题报告:
纯模拟,自己纸上画一画就知道模拟过程了。注意10的18次方,极限情况下64位会溢出的,所以需要特殊打表处理。另一种思路是打表的方式,所有可能的情况最多是2^10次方,将这些数放进有序数组,然后根据输入进行bound_find查找。代码为前一种解法,有点乱!
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
using namespace std;
#define max(x, y) ((x) > (y) ? (x) : (y))
#define min(x, y) ((x) < (y) ? (x) : (y))
typedef long long LL;
LL n;
int GetDigit(LL x)
{
int res = 0;
while (x)
{
++res;
x /= 10;
}
return res;
}
LL GetMaxnumThisDigit(int dig)
{
LL res = 0;
if (dig & 1)
{
return res;
}
for (int i = 0; i < dig/2; ++i)
{
res = res * 10 + 7;
}
for (int i = 0; i < dig/2; ++i)
{
res = res * 10 + 4;
}
return res;
}
LL GetMinnumThisDigit(int dig)
{
LL res = 0;
if (dig & 1)
{
return res;
}
for (int i = 0; i < dig/2; ++i)
{
res = res * 10 + 4;
}
for (int i = 0; i < dig/2; ++i)
{
res = res * 10 + 7;
}
return res;
}
void PrintMinThisDigit(int dig)
{
for (int i = 0; i < dig/2; ++i)
{
printf("4");
}
for (int i = 0; i < dig/2; ++i)
{
printf("7");
}
printf("\n");
}
void Solve()
{
LL ans = 0;
int dig = GetDigit(n);
if ((dig & 1) == 0)
{
// 偶数位
if (n == 0)
{
printf("47\n");
return;
}
if (n > GetMaxnumThisDigit(dig))
{
PrintMinThisDigit(dig+2);
}
else
{
int bits[20] = {0};
int abits[20] = {0};
int tmpId = dig - 1;
LL tmpN = n;
while (tmpN)
{
bits[tmpId--] = tmpN % 10;
tmpN /= 10;
}
int c4 = 0, c7 = 0;
for (int i = 0; i < dig; ++i)
{
if (bits[i] < 4)
{
for (c4; c4 < dig/2; ++c4)
abits[i++] = 4;
for (c7; c7 < dig/2; ++c7)
abits[i++] = 7;
break;
}
else if (bits[i] == 4)
{
if (c4 < dig/2)
{
abits[i] = 4;
++c4;
}
else
{
abits[i] = 7;
++c7;
for (c4; c4 < dig/2; ++c4)
abits[i++] = 4;
for (c7; c7 < dig/2; ++c7)
abits[i++] = 7;
break;
}
}
else if (4 < bits[i] && bits[i] < 7)
{
abits[i++] = 7;
++c7;
for (c4; c4 < dig/2; ++c4)
abits[i++] = 4;
for (c7; c7 < dig/2; ++c7)
abits[i++] = 7;
break;
}
else if (7 == bits[i] && c7 < dig/2)
{
abits[i] = 7;
++c7;
}
else
{
// 向前追溯
for (int j = i - 1; j >= 0; --j)
{
if (abits[j] == 4)
{
abits[j] = 7;
--c4;
++c7;
// 向后填充
for (c4; c4 < dig/2; ++c4)
abits[++j] = 4;
for (c7; c7 < dig/2; ++c7)
abits[++j] = 7;
break;
}
else if (abits[j] == 7)
{
--c7;
}
}
break;
}
}
// calculate
for (int k = 0; k < dig; ++k)
{
printf("%d", abits[k]);
}
printf("\n");
}
}
else
{
// 奇数位
PrintMinThisDigit(dig+1);
}
}
int main()
{
//freopen("input.txt", "r", stdin);
int times;
scanf("%d", ×);
for (int i = 1; i <= times; ++i)
{
//printf("Case #%d:\n", i);
scanf("%lld", &n);
Solve();
}
return 0;
}