hdu 5676-ztr loves lucky numbers
2016-05-14 08:13
411 查看
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.
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.
Output
For each cases
Output the answer
Sample Input
2 4500 47
Sample Output
4747 47
Source
BestCoder Round #82 (div.2)
解题报告:
纯模拟,自己纸上画一画就知道模拟过程了。注意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; }