久違的教學文呢…這次解釋的是不論是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也無關就是了…