H Happy Number
题目描述
Digits 2, 3 and 6 are happy, while all others are unhappy. An integer is happy if it contains only happy digits in its decimal notation. For example, 2, 3, 263 are happy numbers, while 231 is not.
Now Cuber QQ wants to know the n-th happy positive integer.
输入描述:
The first and only line of input contains a positive integer n (1≤n≤10^9).
输出描述:
The first and only line of output contains the n-th happy positive integer.
示例1
输入
680
输出
326623
题目大意:
如果一个正整数中只包含 2 , 3 , 6 2, 3, 6 2,3,6这三种数字中的一种或多种,这个数就被称为happy number。
请输出第n个happy number。
题解:
前一些happy number为2, 3, 6, 22, 23, 26, 32, 33, 36, 62, 63, 66,222…
我们可以发现每一位上只会出现2, 3, 6这三个数字,很像3进制的表达方式,所以只需要将n - 1转化成3进制,再将0换成2,1换成3,2换成6即可。实际验证中会发现会出错,原因是6“进位”时下一个数变成了32而不是22,如果我们将happy number按1位、2位、3位等数按位数划分开来,就可以避免这个错误。
我们可以发现1位的happy number有31个,2位的happy number有32个,3位的happy number有33,所以我们可以判断出第n个happy number有几位,算出第n个happy number是第x个n位的happy number。将x - 1转换成3进制,并高位补零到n位,将012替换为236就是我们要求的答案。
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int ans[] = {2, 3, 6};
ll sum[] = {0, 3, 12, 39, 120, 363, 1092, 3279, 9840, 29523, 88572, 265719, 797160, 2391483, 7174452, 21523359, 64570080, 193710243, 581130732, 1743392199, 5230176600,};
string work(int n) { // 返回n - 1的3进制
n --;
if (n == 0) return "0";
string res = "";
while (n > 0) {
int t = n % 3;
res += to_string(t);
n /= 3;
}
return res;
}
int main() {
ll n;
cin >> n;
ll pos = 0;
while (n > sum[pos]) pos ++; // 判断第n个happy number是n位的第几个数
string s = work(n - sum[pos - 1]); // 计算3进制
if (s.length() < (pos)) // 位数不够高位补0
for (int i = s.length(); i <= pos - 1; i ++)
s += "0";
reverse(s.begin(), s.end());
for (ll i = 0; i < s.length(); i ++) // 将3进制数0换成2, 1换成3, 2换成6
cout << ans[s[i] - '0'];
cout << '\n';
return 0;
}