久违的教学文呢…这次解释的是不论是SMA还是其他高阶语言都会用到的一些技巧…
那这次的的范例是从
某处看到后引起好奇而写的…
题目的规则:
给定一个整数,你必须以下列的方式产生出另一个整数:
1. 将该数的每一个位数由大到小排列。
2. 将该数的每一个位数由小到大排列。
3. 将上述第一步骤所得的数减掉第二步骤所得的数,产生另一个数。
4. 重复上述步骤,直到出现重复的数字为止。
并输出该数值所产生出"执行次数"。
范例:
Input:
1234
Output:
4321
1234
4321 - 1234 = 3087
8730 - 378 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
最后输出的数值:4
以上的规则是来自
黑洞数…
至于数学什么的身为
过期的大学生早就忘记那是什么啦…
好啦…虽然这好像也是个重点…姑且无视…这个题目的规则用到的技巧有三个(大概):
1在阵列中比较数值大小并取得最大最小值的阵列位置
2将阵列中的数值重新排列,每个人的排法可能会有差异,我是用「不重复的随机乱数」这写法
3当执行次数只有一次时让未知的执行次数用回圈跑出来
然后这教学的重点…程式码:
故意写成CS版的…某些学生以为捡到现成的程式想偷懒复制贴上的话…这样不行喔~╱/( ◕‿‿◕ )\╲复制程式
public plugin_init()
{
register_plugin("Kaprekar constant", "1.0", "MyChat:a7811311622")
register_concmd("Kaprekar_constant", "kaprekar_constant") // 注册控制台指令
}
public kaprekar_constant(id)
{
new text[100], text_1[100], text_2[100], text_3[100]
new i, j, k, num
read_argv(1, text, sizeof text - 1) // 读取输入的数值
if (!(3 <= strlen(text) <= 4)) return PLUGIN_HANDLED; // 卡布列克常数三位数和四位数的黑洞数只有一个,才列入程式考量
while (!equal(text, text_3)) // 只要第一步骤减掉第二步骤的数和原本的数一样就终结回圈
{
num++ // 计数
if (strlen(text_3)) copy(text, charsmax(text), text_3) // 第三步骤有算出来数才执行第四步骤
copy(text_1, charsmax(text_1), text) // 最初的数复制给第一步骤的数
copy(text_2, charsmax(text_2), text) // 最初的数复制给第二步骤的数
// 个人比较懒,不想每个位数都要计算,所以比大小我就直接拿字元的ASCII码比大小
// '0' = 48、'1' = 49、'2' = 50......'9' = 57
for (i = 0; i < strlen(text_1); i++) // 从大排到小
{
new max = 0 // ASCII码最小从0开始
for (j = i; j < strlen(text_1); j++) // 扫描一遍每位的数字大小,从中比较并取得最大的数
{
if (text_1[j] > max)
{
max = text_1[j] // 这里的max是用来记忆最大的数值是多少
k = j // 记忆最大数的阵列位置
}
}
// 扫描过后将最大数的位置和最前面数字的位置交换,这写法常见于「不重复的随机乱数」
max = text_1[k] // 这里的max不再是比大小,只是单纯的暂存数,不想又宣告一个 temp 嘛…
text_1[k] = text_1[i]
text_1[i] = max // 如果没用暂存数记忆的话,这时的text_1[k]已经是text_1[i]了,程式就不记得text_1[k]的数是多少了
// i = 0 时我将数字中最大的数和最左边(最高位数)的数交换了,接下来的 j = i 在比较时就不会比较到上一个最大数
// 例如范例 1234 这时便成 4231,第二层回圈因为 j = i 会取扫描 231 来比大小,i = 1 时就变成 4321
}
// 打了好多字…懒的打…同上…(<ゝω・)
for (i = 0; i < strlen(text_2); i++)
{
new min = 255 // 比大小时「最大」的数总是给最小的…「最小」的数反而给最大的…
for (j = i; j < strlen(text_2); j++)
{
if (text_2[j] < min)
{
min = text_2[j]
k = j
}
}
min = text_2[k]
text_2[k] = text_2[i]
text_2[i] = min
}
num_to_str(str_to_num(text_1) - str_to_num(text_2), text_3, charsmax(text_3)) // 第三步骤
console_print(id, "%s %s %s %s %d", text, text_1, text_2, text_3, num) // 输出所有的数和目前跑了几次回圈
}
return PLUGIN_HANDLED;
}
结果:
反正这教学跟现在€$◎无关…不觉得会被盗…
虽然和CS也无关就是了…