NC54510. 小乐乐与二段数
描述
小乐乐从老师口中听到了二段数这个名词,想更深入的了解二段数。
二段数是这样的正整数:恰好包含两种不同的十进制数字s和t,s不是0,并且s的所有出现均排列在所有的t的前面。例如,44444411是二段数(s是4,t是1),41、10000000和5555556也是。但4444114和44444都不是二段数。
这时老师问小乐乐:给你一个任意的正整数n,你能求出比n大并且是n的倍数的最小二段数吗?请你帮助小乐乐解答这个问题。
输入描述
多组输入,每组输入包含一个正整数n (1 ≤ n ≤ 99999)
题目保证测试数据总数不超过500组,当输入n=0时程序结束。
输出描述
对于每组测试用例,输出正整数n,后面紧跟“: ”,输出答案并换行,即比n大且是n的倍数的最小二段数。
示例1
输入:
1 2019 0
输出:
1: 10 2019: 9999999993
C++11(clang++ 3.9) 解法, 执行用时: 65ms, 内存消耗: 4744K, 提交时间: 2019-11-09 10:20:53
#include<bits/stdc++.h> using namespace std; int main() { int n; while(cin>>n && n) { string ans = n-1 ? "" : "10"; if(n > 1) { vector<int> hash[100100]; for(int i = 1, flag = 1, r1 = 1, r; flag; r1 = (r1 * 10 + 1) % n, i++) for(int j = -9; j < 10; j++) if(j) { r = ((r1*j) % n + n) % n; if(r && i > 1 && j > 0 && hash[r].size()) for(int k = 0; k < hash[r].size(); k++) { int digit = hash[r][k] % 100 - 9; int cnt = hash[r][k] / 100; int suffixd = j - digit; if(cnt < i && suffixd >= 0 && suffixd < 10) { string tmp; for(int kk = 0; kk < i; kk++) tmp += char((kk < i-cnt ? j : suffixd) + '0'); if(tmp != to_string(n) && (ans == "" || tmp < ans)) flag = 0, ans = tmp; } } hash[r].push_back(i*100+j+9); } } printf("%d: %s\n", n, ans.data()); } }