The #A1452 砝码称重 is very difficult.

Let me teach you.

I. 顶以遍亮

//  ↓物品重量   ↓结果长度   ↓最大位权,用于最后从大到小输出
int n, a[10], len = 1,    x = 1;
//     ↑最后结果的三进制串和n的三进制
//         (为什么是三进制?)

II. 度踢

提炼有用信息:

砝码的重量分别为 1g3g9g6561g1g,3g,9g,……,6561g

(3的整数次幂)

结合这道题所在的章节“进制、机器码与位运算”,这个(3的整数次幂)就是在暗示 要用三进制

按重量从大到小的顺序输出

与物品同侧的砝码用负号表示,与物品异侧的砝码用正号表示

知道了关键信息,接下来就要开始写⑩了

III. 写⑩

已知要用三进制,那该怎么用呢?

1 转三进制

直接反复%3就好力

// 选择for而不是while因为要下标遍历 
for (int i = 1; n /*只要n还有数就继续*/; i++, x *= 3)
{
//  短除法: 
	a[i] = n % 3;
	n /= 3;
}

2 逐位判断加法码

1) 是1怎么办?

a[i] == 1成立时说明砝码另一侧需要加砝码,但a数组既是n的三进制也是输出内容,所以不做处理

2) 是2怎么办?

a[i] == 2成立时,因为天平有一侧只有砝码,砝码重量和特征在三进制中只有0/1,说明另一侧物品+砝码也要凑成三进制中只有0/1,所以要把2凑成0,怎么把2凑成0呢?

答:在物品一侧加砝码

怎么实现呢?

答:在物品一侧加砝码拢共分三↗步

①加砝码

因为题目规定在输出时要把和物品同侧的砝码以负数形式输出,所以把a[i]设为-1就好,在输出时直接将砝码数乘以a[i]就好力

②物品侧重量?

因为加了砝码,所以本来的a[i]就会变成33,但是三进制需要进位,所以n++

③休息

写代码写累了喝口水歇会

2) 是0怎么办?

不用动

3 输出

这个环节就体现出x和使用三进制的优越性了

循环后x就会变成我们最大的位权,所以我们直接倒序遍历a变量,输出a[i] * x(因为之前我们已经将与物品同侧加的砝码处的a[i]设为-1,所以输出与物品同侧加的砝码时不用担心出错)

同时,使用三进制存储也就意味着达成了“按重量从大到小的顺序输出”,因为位权在倒序输出时就是按从大到小的顺序的

tip:每次循环之后都要x /= 3,以做到位权递减输出

把所有的都写上就AC力