AT_past202107_g 题解
0x00AC3375 · · 题解
前言
本题可以视为平衡三进制的模版题。
1. 前置知识 - 平衡三进制
平衡三进制是一种以
例如要将平衡三进制下的数字
从上面的计算流程中我们很容易看出,对于一个给定的十进制数字
由于平衡三进制不同于常规的三进制,其涉及到负数的数位,因此直接将十进制转化为平衡三进制可能有些困难,为此我们可以先将十进制转化为常规三进制,再转化为平衡三进制。
2. 十进制转化为常规三进制
十进制转化为普通三进制,只需要重复“模
int tp[100];
void dec2base3(long long t) //将十进制转化为普通三进制, 使用数组存储每一位, 下标小的表示低位, 下标大的表示高位
{
int index = 0;//当前的数位
while (t)
{
tp[index] = t % 3;
t /= 3;
index += 1;
}
return;
}
3. 常规三进制转化为平衡三进制
由于
void base2balance3()//将普通三进制转化为平衡三进制, 平衡三进制的每一位由-1, 0或1构成
{
for (int i = 0; i <= 99; i += 1)
{
if (tp[i] == 2)//如果某一位是2, 这一位就变成-1, 然后高位增加1
{
tp[i] = -1;
tp[i + 1] += 1;
}
if (tp[i] == 3)//如果某一位是3, 和普通三进制一样, 要进位
{
tp[i] = 0;
tp[i + 1] += 1;
}
}
}
4. 输出
按照平衡三进制的序列,输出
参考代码:
for (index = 99; index >= 0; index -= 1) if (tp[index]) break;//找到第一个不为零的数位
for (int i = index; i >= 0; i -= 1) if (tp[i]) tot += 1;/*平衡三进制如果某一位是0, 就不输出, 所以要判断总共要输出多少位!*/
printf("%d\n", tot);
for (int i = index; i >= 0; i -= 1) if(tp[i]) printf("%.0Lf ", powl(3.L, i) * tp[i]);
5. 完整代码
#pragma warning(disable:4996)
#include <cstdio>
#include <algorithm>
#include <cmath>
long long n, index, tot = 0;
int tp[100];
void dec2base3(long long t) //将十进制转化为普通三进制, 使用数组存储每一位, 下标小的表示低位, 下标大的表示高位
{
int index = 0;//当前的数位
while (t)
{
tp[index] = t % 3;
t /= 3;
index += 1;
}
return;
}
void base2balance3()//将普通三进制转化为平衡三进制, 平衡三进制的每一位由-1, 0或1构成
{
for (int i = 0; i <= 99; i += 1)
{
if (tp[i] == 2)//如果某一位是2, 这一位就变成-1, 然后高位增加1
{
tp[i] = -1;
tp[i + 1] += 1;
}
if (tp[i] == 3)//如果某一位是3, 和普通三进制一样, 要进位
{
tp[i] = 0;
tp[i + 1] += 1;
}
}
}
int main()
{
scanf("%lld", &n);
dec2base3(n);
base2balance3();
/*调试用代码块 - 一般用Z表示-1, 倒序输出即可得到输入整数的平衡三进制的序列
for (int i = 99; i >= 0; i -= 1)
{
if (tp[i] == 0) putchar('0');
if (tp[i] == -1) putchar('Z');
if (tp[i] == 1) putchar('1');
}
*/
for (index = 99; index >= 0; index -= 1) if (tp[index]) break;
for (int i = index; i >= 0; i -= 1) if (tp[i]) tot += 1;/*平衡三进制如果某一位是0, 就不输出, 所以要判断总共要输出多少位!*/
printf("%d\n", tot);
for (int i = index; i >= 0; i -= 1) if(tp[i]) printf("%.0Lf ", powl(3.L, i) * tp[i]);
}