伊莉討論區

標題: 請教一下四則運算的邏輯思路? [打印本頁]

作者: lonercity    時間: 2020-3-3 06:42 AM     標題: 請教一下四則運算的邏輯思路?

?+?-?+?=8   ?+?*?-?=6  ?有3或4個 然後做加減乘除之後等式成立
?只能填1-9且不能重複
以上面例子 我輸入=8   =6
程式運算後自動給出?的數字 所有組合  
2+9-4+1=8   1+4*2-3=6
9+2-4+1=8   3+2*4-5=6
7+4-5+2=8   1+3*4-7=6
:                    :
:                    :
:                    :





作者: gonewang123    時間: 2020-3-3 09:46 AM

Hello :

小弟資質駑鈍,how about 四層迴圈

for i1 = 0 to 9
   for i2= 0 to 9
       for i3 = 0 to 9
            for i4 = 0 to 9
                 if math expression equal
                 ....do something
                 式一,最多僅一解
                 式二,最多僅二解
            next i4
       next i3
   next i2
next i1

thank you
作者: stephenwei_lu    時間: 2020-3-3 11:30 AM

我的想法也沒什麼思考.

scanf 讀幾個 運算單元 X
依序輸入 運算 單元
再輸入要得到的result
Y = X+1
Y就是你的for值的第一圈
這樣依序下去
可以判斷4則的優先權, 先處理一下



作者: gonewang123    時間: 2020-3-3 05:39 PM

你是指
recursion ?

追加一些判斷式可以增加運算效率,找到答案的step (in loop)
就可以跳出,進行下一個。

其實我發現有個判斷式,但是應該沒什麼作用。
如果:  x1 ~ x4 當作輸出結果
有個關係:
4 <= sqrt(x1^2 + x2^2 + x3^2 + x4^2) <= 18

我只是來賺積分。。。
作者: lonercity    時間: 2020-3-4 07:02 AM

本帖最後由 lonercity 於 2020-3-4 07:31 AM 編輯
gonewang123 發表於 2020-3-3 09:46 AM [url=forum.php?mod=redirect&goto=findpost&pid=319707458&ptid=12561213][/url]
Hello :

小弟資質駑鈍,how about 四層迴圈

以我舉的例子 式一 不可能只一組 解 我KEY的就三組了 式二也是還有 1-9是? 你只能輸入答案  就是=後面的數字  
輸入答案後 程式去運算出所有 ?可以有的組合 這些組合中?只能是數字1-9 且不重複

作者: lonercity    時間: 2020-3-4 07:13 AM

stephenwei_lu 發表於 2020-3-3 11:30 AM
我的想法也沒什麼思考.

scanf 讀幾個 運算單元 X

我的想法也是 四則運算優先權先寫好。
求解的話 我是會用反向運算
例如: 1+3=4  當不知道1 3 兩數字在題目中是?? 而4是自己輸入的
我會反過來4-?-?=0   
設定好條件判斷把?1-9重複的砍掉 不然程式跑出一組 4-2-2=0 也算入一組答案
這樣應該能獲得所有答案
   
作者: gonewang123    時間: 2020-3-4 08:58 AM

lonercity 發表於 2020-3-4 07:02 AM
以我舉的例子 式一 不可能只一組 解 我KEY的就三組了 式二也是還有 1-9是? 你只能輸入答案  就是=後面的數 ...

Hi :

這樣是不是不小心又賺到一點積分了?。。。
我說的是四層迴圈,判斷一組解是在迴圈最內層喔。
是為了效率。
當然也是可以全部都掃描過,共 9^4 次判斷,也還好啦,以目前的PC硬體水準來講。

作者: gonewang123    時間: 2020-3-4 09:22 AM

其實,我有點憂心。。。
我在想,在這邊我是不是忘記放個"0"在迴圈當中。
數字有可能是"0"嗎?
你的問題允許出現"0" ?

確認一下。
thank you

作者: lonercity    時間: 2020-3-4 11:17 AM

gonewang123 發表於 2020-3-4 09:22 AM
其實,我有點憂心。。。
我在想,在這邊我是不是忘記放個"0"在迴圈當中。
數字有可能是"0"嗎?

?是由程式算出 不重複的1-9 數字沒有0這個數  
等式後面的才是由USER輸入
?+?*?-?=8    這個8 你可以輸入 前面? 是程式跑完得出1-9中的數字(沒有0喔)且不能重複到

作者: gonewang123    時間: 2020-3-4 01:33 PM

Well...

我想到另一個也許會比較有效率的方式。
你可以將方程式稍作整理。
譬如:
?+?-?+?=8 ,當中應該會先宣告 x1, x2, x3, x4 當作裡面的 "?" (各自依照順序)
其中 x3 (左數到右第三個),是屬於 "負",將他移到右邊(國中數學)
會變成, x1 + x2 + x4 = "8" + x3
當中的 "8",是一開始就指定的。
然後跑回圈。。。
由 x3 = 1 to 9 開始
當 x3 = 1,右邊是 "9"
此時左邊 :
x1 = 1 to 9
    x2 = 1 to 9
          x4 = 1 to 9
                 if (x1 + x2 + x4) > 9
                      break;
                 運算。。。判斷
          next x3
    next x2
next x1

也許判斷上會比較少跑一些步驟。

作者: gonewang123    時間: 2020-3-4 03:06 PM

另一個更有效率的方式。
我想到就是用 recursive 的方式。
依上述,也是將四個變數命名為: x1, x2, x3, x4
依照輸入:8,右邊整理成 8+x3

然後撰寫一個 recursion,目的是將一個數字依序拆成兩個數字
依照這個recursion,可以將,譬如:x3=1,右邊是 9
x1, x2, x4 當作三個空格:
sep(9) -> x1 = 1, x2 = 8 ,
但是因為 x4 = empty, 所以繼續 sep(x2) 就是 sep(8) -> x2 = 1, x4 = 7
返回得到:[1, 1, 7]
繼續 x2 = 2, x4 = 6 ... 直到 x2 = 4 >= 8/2;

跳回 x1
x1 = 2, ...繼續上述
直到 x1 = 3 >= 8/3...
這樣就得到 [x1, x2, x4] 不排列的組合。

應該可以少跑很多步驟,不過程式邏輯要很強。。。可以視為一個挑戰。

FYI
作者: tryit244178    時間: 2020-3-5 08:33 AM

本帖最後由 tryit244178 於 2020-3-5 08:39 AM 編輯

2樓大大的方法不就可以了。要效率的話,也許可以參考Backtracking
http://www.csie.ntnu.edu.tw/~u91029/Backtracking.html


作者: gonewang123    時間: 2020-3-5 03:19 PM

Hello :

感謝大大的支持,很有用的連結資源喔。
因為"小小"->我非資訊類科班,想請問是否有這種探討解問題方式的"演算法"的相關書籍可以參考?
類似網頁當中的"8皇后"問題。。。

小小感恩。。。
作者: tryit244178    時間: 2020-3-5 09:28 PM

本帖最後由 tryit244178 於 2020-3-5 09:46 PM 編輯
gonewang123 發表於 2020-3-5 03:19 PM
Hello :

感謝大大的支持,很有用的連結資源喔。

應該有吧。大大你可以去圖書館找看看

關於你10樓的回答,我看了後有二項疑問
第一、移項後,應該還是要判斷該項是否重覆,我認為應該不會比較快
第二、 if (x1 + x2 + x4) > 9 ,大於9的話,不就加起來超過也會被判斷是對等式?


所以我寫了個 javascript 來求證。(用網頁就行了,連軟體都不用裝XD)
  1. <!doctype html>

  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Test</title>
  6. <script>
  7. function test1()
  8. {
  9.   let result = "";
  10.   let count = 0;

  11.   for (let i=1; i<10; i++) {
  12.     for (let j=1; j<10; j++) {
  13.       if (j===i)
  14.         continue;

  15.       for (let k=1; k<10; k++) {
  16.         if (i===k || j===k)
  17.           continue;

  18.         for (let l=1; l<10; l++) {
  19.           count++;
  20.           if (i===l || j===l || k===l)
  21.             continue;

  22.           if (i+j-k+l===8)
  23.             result += i + "+" + j + "-" + k + "+" + l + "\n";
  24.         }
  25.       }
  26.     }
  27.   }

  28.   result += "迴圈次數:" + count;
  29.   document.getElementById("result1").value = result;
  30. }

  31. function test2()
  32. {
  33.   let result =  "";
  34.   let count = 0;

  35.   for (let k=1; k<10; k++) {
  36.     for (let i=1; i<10; i++) {
  37.       if (k===i)
  38.         continue;

  39.       for (let j=1; j<10; j++) {
  40.         if (i===j || k===j)
  41.           continue;

  42.         for (let l=1; l<10; l++) {
  43.           count++;
  44.           if (i===l || j===l || k===l)
  45.             continue;

  46.           if (i+j+l === 8+k)
  47.             result += i + "+" + j + "-" + k + "+" + l + "\n";
  48.         }
  49.       }
  50.     }
  51.   }

  52.   result += "迴圈次數:" + count;
  53.   document.getElementById("result2").value = result;
  54. }

  55. function test()
  56. {
  57.   test1();
  58.   test2();
  59. }
  60. </script>
  61. </head>
  62. <body>
  63. <button onclick="test()">Test</button></br>
  64. <textarea cols="10" rows="30" id="result1" spellcheck="false"></textarea>
  65. <textarea cols="10" rows="30" id="result2" spellcheck="false"></textarea>
  66. </body>
  67. </html>
複製代碼




補充內容 (2020-3-5 09:30 PM):
可以把第57行改成大於試試

補充內容 (2020-3-5 09:33 PM):
第28行和第58行,最後的換行,要把2條斜線改成1條…
作者: gonewang123    時間: 2020-3-5 10:00 PM

tryit244178 發表於 2020-3-5 09:28 PM
應該有吧。大大你可以去圖書館找看看

關於你10樓的回答,我看了後有二項疑問

Hi :

你的點子不錯耶,用 Javascript 就可以初步驗證。
試試看下面的。。。不過order 是以 "負值"為主進行排列
  1. <!doctype html>

  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Test</title>
  6. <script>
  7. function test1()
  8. {
  9.   let result = "";
  10.   let count = 0;

  11.   for (let i=1; i<10; i++) {
  12.     for (let j=1; j<10; j++) {
  13.       if (j===i)
  14.         continue;

  15.       for (let k=1; k<10; k++) {
  16.         if (i===k || j===k)
  17.           continue;

  18.         for (let l=1; l<10; l++) {
  19.           count++;
  20.           if (i===l || j===l || k===l)
  21.             continue;

  22.           if (i+j-k+l===8)
  23.             result += i + "+" + j + "-" + k + "+" + l + "/\n";
  24.         }
  25.       }
  26.     }
  27.   }

  28.   result += "迴圈次數:" + count;
  29.   document.getElementById("result1").value = result;
  30. }

  31. function test2()
  32. {
  33.   let result =  "";
  34.   let count = 0;
  35.   let right_val = 0;

  36.   for (let i=1; i<10; i++) {
  37.     right_val = 8 + i;
  38.     for (let j=1; j<10; j++) {
  39.       if (j > right_val || j==i)
  40.         continue;

  41.       for (let k=1; k<10; k++) {
  42.         if (k==i || k===j || ( (j+k) > right_val) )
  43.           continue;

  44.         for (let l=1; l<10; l++) {
  45.           count++;
  46.           if ( l==i || l===j || l===k || ( (j+k+l) > right_val) )
  47.             continue;

  48.           if (k+j+l === right_val)
  49.             result += k + "+" + j + "-" + i + "+" + l + "/\n";
  50.         }
  51.       }
  52.     }
  53.   }

  54.   result += "迴圈次數:" + count;
  55.   document.getElementById("result2").value = result;
  56. }

  57. function test()
  58. {
  59.   test1();
  60.   test2();
  61. }
  62. </script>
  63. </head>
  64. <body>
  65. <button onclick="test()">Test</button></br>
  66. <textarea cols="10" rows="30" id="result1" spellcheck="false"></textarea>
  67. <textarea cols="10" rows="30" id="result2" spellcheck="false"></textarea>
  68. </body>
  69. </html>
複製代碼

作者: gonewang123    時間: 2020-3-6 08:42 AM

Hello :

不好意思。我剛剛查一下 continue & break 在 Javascript 的差別。
一個是跳出迴圈(break),一個是省略當次(i),繼續執行下次(i+1)

所以,其實code 可以再更效率化。
我想增加效率應該是可以再改進,只是看是不是要投資時間在上面而已。
  1. <!doctype html>

  2. <html>
  3. <head>
  4. <meta charset="BIG5">
  5. <title>Test</title>
  6. <script>
  7. function test1()
  8. {
  9.   let result = "";
  10.   let count = 0;

  11.   for (let i=1; i<10; i++) {
  12.     for (let j=1; j<10; j++) {
  13.       if (j===i)
  14.         continue;

  15.       for (let k=1; k<10; k++) {
  16.         if (i===k || j===k)
  17.           continue;

  18.         for (let l=1; l<10; l++) {
  19.           count++;
  20.           if (i===l || j===l || k===l)
  21.             continue;

  22.           if (i+j-k+l===8)
  23.             result += i + "+" + j + "-" + k + "+" + l + "\n";
  24.         }
  25.       }
  26.     }
  27.   }

  28.   result += "迴圈次數:" + count;
  29.   document.getElementById("result1").value = result;
  30. }

  31. function test2()
  32. {
  33.   let result =  "";
  34.   let count = 0;
  35.   let right_val = 0;

  36.   for (let i=1; i<10; i++) {
  37.     right_val = 8 + i;
  38.     for (let j=1; j<10; j++) {
  39.           if(j+2 > right_val ) break;
  40.       if (j==i)
  41.         continue;

  42.       for (let k=1; k<10; k++) {
  43.             if(j+k+1 > right_val ) break;
  44.         if (k==i || k===j )
  45.           continue;

  46.         for (let l=1; l<10; l++) {
  47.           count++;
  48.                   if(j+k+l > right_val ) break;
  49.           if ( l==i || l===j || l===k)
  50.             continue;

  51.           if (k+j+l === right_val)
  52.             result += k + "+" + j + "-" + i + "+" + l + "\n";
  53.         }
  54.       }
  55.     }
  56.   }

  57.   result += "迴圈次數:" + count;
  58.   document.getElementById("result2").value = result;
  59. }

  60. function test()
  61. {
  62.   test1();
  63.   test2();
  64. }
  65. </script>
  66. </head>
  67. <body>
  68. <button onclick="test()">Test</button></br>
  69. <textarea cols="10" rows="30" id="result1" spellcheck="false"></textarea>
  70. <textarea cols="10" rows="30" id="result2" spellcheck="false"></textarea>
  71. </body>
  72. </html>
複製代碼

作者: tryit244178    時間: 2020-3-6 12:05 PM

本帖最後由 tryit244178 於 2020-3-6 12:59 PM 編輯

搞懂了10樓,順便把11樓也弄了。效率差真多

大大這種程度,圖書館的書應該沒辦法滿足你…
  1. <!doctype html>

  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Test</title>
  6. <script>
  7. var VVV = 8;
  8. function test1()
  9. {
  10.   let result = "";
  11.   let count = 0;

  12.   for (let i=1; i<10; i++) {
  13.     for (let j=1; j<10; j++) {
  14.       if (j===i)
  15.         continue;

  16.       for (let k=1; k<10; k++) {
  17.         if (i===k || j===k)
  18.           continue;

  19.         for (let l=1; l<10; l++) {
  20.           count++;
  21.           if (i===l || j===l || k===l)
  22.             continue;

  23.           if (i+j-k+l===VVV)
  24.             result += i + "+" + j + "-" + k + "+" + l + "\n";
  25.         }
  26.       }
  27.     }
  28.   }

  29.   result += "迴圈次數:" + count;
  30.   document.getElementById("result1").value = result;
  31. }

  32. function test2()
  33. {
  34.   let result =  "";
  35.   let count = 0;
  36.   let right_val = 0;

  37.   for (let i=1; i<10; i++) {
  38.     right_val = VVV + i;

  39.     for (let j=1; j<10; j++) {
  40.       if (j > right_val || j==i)
  41.         continue;

  42.       for (let k=1; k<10; k++) {
  43.         if (k==i || k===j || ( (j+k) > right_val) )
  44.           continue;

  45.         for (let l=1; l<10; l++) {
  46.           count++;
  47.           if ( l==i || l===j || l===k || ( (j+k+l) > right_val) )
  48.             continue;

  49.           if (k+j+l === right_val)
  50.             result += k + "+" + j + "-" + i + "+" + l + "\n";
  51.         }
  52.       }
  53.     }
  54.   }

  55.   result += "迴圈次數:" + count;
  56.   document.getElementById("result2").value = result;
  57. }

  58. function test3()
  59. {
  60.   let result =  "";
  61.   let count = 0;
  62.   let right_val = 0;

  63.   for (let i=1; i<10; i++) {
  64.     right_val = VVV + i;

  65.     for (let j=1; j<10; j++) {
  66.       if (j > right_val)
  67.         break;
  68.       if (j===i)
  69.         continue;

  70.       for (let k=1; k<10; k++) {
  71.         if ((j+k) > right_val)
  72.           break;
  73.         if (k==i || k===j)
  74.           continue;

  75.         for (let l=1; l<10; l++) {
  76.           count++;
  77.           if ((j+k+l) > right_val)
  78.             break;
  79.           if ( l==i || l===j || l===k)
  80.             continue;

  81.           if (k+j+l === right_val)
  82.             result += k + "+" + j + "-" + i + "+" + l + "\n";
  83.         }
  84.       }
  85.     }
  86.   }

  87.   result += "迴圈次數:" + count;
  88.   document.getElementById("result3").value = result;
  89. }

  90. function test4()
  91. {
  92.   let result =  "";
  93.   let count = 0;
  94.   let right_val = 0;

  95.   for (let i=1; i<10; i++) {
  96.     right_val = VVV + i;

  97.     for (let j=1; j<10; j++) {
  98.       if (j > right_val)
  99.         break;
  100.       if (j===i)
  101.         continue;

  102.       for (let k=1; k<10; k++) {
  103.         count++;

  104.         if (k==i || k===j)
  105.           continue;

  106.         let tmpK = right_val-j-k;
  107.         if (tmpK===i || tmpK===j || tmpK===k || tmpK<1 || tmpK>9)
  108.           continue;

  109.         result += j + "+" + k + "-" + i + "+" + tmpK + "\n";
  110.       }
  111.     }
  112.   }

  113.   result += "迴圈次數:" + count;
  114.   document.getElementById("result4").value = result;
  115. }

  116. function test()
  117. {
  118.   test1();
  119.   test2();
  120.   test3();
  121.   test4();
  122. }
  123. </script>
  124. </head>
  125. <body>
  126. <button onclick="test()">Test</button><br />
  127. <textarea cols="10" rows="30" id="result1" spellcheck="false"></textarea>
  128. <textarea cols="10" rows="30" id="result2" spellcheck="false"></textarea>
  129. <textarea cols="10" rows="30" id="result3" spellcheck="false"></textarea>
  130. <textarea cols="10" rows="30" id="result4" spellcheck="false"></textarea>
  131. </body>
  132. </html>
複製代碼



作者: gonewang123    時間: 2020-3-10 09:29 AM

Hi :

真是謝謝大大,辛苦了。

小小發現這幾天沒什麼新po。
突然想到小小小碰到的一個數學問題。他是這樣寫的:

"小小小"牽 A,B,C,D 四頭牛,從甲地出發過河到乙地。
A 過河需要花1分鐘
B 過河需要花2分鐘
C 過河需要花5分鐘
D 過河需要花6分鐘

每次過河最多只能兩頭牛一起過去,"小小小"需要坐在牛背上一起牽牛。
請問,將四頭牛都過河到乙地,最少得花多少時間?

我在想這樣的問題。。。

thank you
作者: tryit244178    時間: 2020-3-10 12:37 PM

gonewang123 發表於 2020-3-10 09:29 AM
Hi :

真是謝謝大大,辛苦了。

我去看了解答後,我想這樣回答
小小小坐在D,把D放在C上,把C放在B上,把B放在A上。1分鐘就能過河




歡迎光臨 伊莉討論區 (http://a401.file-static.com/) Powered by Discuz!