Upgrade to Pro — share decks privately, control downloads, hide ads and more …

数学未履修から始める競プロチュートリアル

zk-phi
December 22, 2019

 数学未履修から始める競プロチュートリアル

身内でやった勉強会でやったチュートリアルです。競技プログラミングの遊び方、基本的なアルゴリズムなどを、なるべく数学や情報工学の専門用語を排除しながら説明してみました。すべてを「使いこなせれば」ABC D 完くらいまでは狙えると思います。

zk-phi

December 22, 2019
Tweet

More Decks by zk-phi

Other Decks in Programming

Transcript

  1. # 一行読み込んで、空白でぶった切る a1, a2, a3 = input().split() # 整数 (int)

    に変換して足し算 sum = int(a1) + int(a2) + int(a3) if sum >=22: print(“bust”) else: print(sum) // scanf, printf を使うのに必要 #include <stdio.h> int main (void) { int a1, a2, a3, sum; // scanf は int への変換も込み scanf(“%d %d %d”, &a1, &a2, &a3); if ((sum = a1 + a2 + a3) >= 22) { printf(“bust¥n”); } else { printf(“%d¥n”, sum); } } 1ZUIPOͷྫ $ͷྫ
  2. # 一行読み込んで整数に変換 n = int(input()) # ループで全通り実験してみる for i in

    range(1, 10): for j in range(1, 10): if i * j == n: # 一致したら “Yes”と言って終わり print(“Yes”); exit() # 見つからなかったので No print(“No”) #include <stdio.h> int main (void) { int n, i, j; scanf(“%d”, &n); for (i = 0; i < 10; i++) for (j = 0; j < 10; j++) if (i * j == n) { printf(“Yes¥n”); return 0; } printf(“No¥n”); } 1ZUIPOͷྫ $ͷྫ
  3. n = int(input()) for i in range(1, 10): if n

    % i == 0 and n / i < 10: print(“Yes”); exit() print(“No”) #include <stdio.h> int main (void) { int n, i; scanf(“%d”, &n); for (i = 1; i < 10; i++) if (n % i == 0 && n / i < 10) { printf(“Yes¥n”); return 0; } printf(“No¥n”); } 1ZUIPOͷྫ $ͷྫ
  4. "#$$#VZBO*OUFHFS վ ɾd?·Ͱͷ੔਺Λച͍ͬͯΔ͓ళ͕͋Δ ɾ੔਺ /ͷ஋ஈ͸ʮ/ 㲋/ʯ ੾Γ্͛ ྫ͸  ԁ

    ɾॴ࣋ۚ Y͕༩͑ΒΕΔͷͰɺߪೖͰ͖Δ࠷େͷ੔਺Λݟ͚ͭΖ ߟ࡯ ɾ࠷େͰ ?·Ͱങ͑ΔͷͰ૯౰ͨΓ͸͔͔࣌ؒΓͦ͏ʜ
  5. import math x = int(input()) bottom = 0 // 絶対買える

    top = x // 絶対買えない while top – bottom > 1: med = (top + bottom) // 2 if med + math.sqrt(med) > x: top = med else: bottom = med print (bottom) #include <stdio.h> #include <math.h> int main (void) { int x, bottom, top; scanf(“%d”, &x); top = x, bottom = 0; while (top – bottom > 0) { int med = (top + bottom) / 2; if (med + sqrt(med) > x) top = med; else bottom = med; } printf(“%d¥n”, bottom); } 1ZUIPOͷྫ $ͷྫ
  6. ΞϧΰϦζϜͷʮ଎͞ʯ ɾMPH/ͳ΋ͷͷྫ ɾೋ෼୳ࡧ ʜݕࡧൣғ͕  ഒʹͳͬͯ΋ TUFQ਺͸  ɾ੔਺ͷܻ਺ ʜେ͖͕͞

    ഒʹͳͬͯ΋ܻ਺͸  ɾϚάχνϡʔυ ʜΤωϧΪʔ͕ഒʹͳͬͯ΋ .͸  ɾʮ˓˓ഒʹͳͬͯ΋  ͚ͩʯͳ΋ͷ͸ MPH/
  7. ྫ୊ $ऑ͘Β͍ʁ ྫɿ     PL  PL

      OH    OH
  8. ྫ୊ $ऑ͘Β͍ʁ ྫɿ     PL  PL

      OH    OH PL
  9. ྫ୊ $ऑ͘Β͍ʁ ྫɿ     PL  PL

      OH    OH PL  PL
  10. ྫ୊ $ऑ͘Β͍ʁ ྫɿ     PL  PL

      OH    OH PL  PL   OH
  11. ྫ୊ $ऑ͘Β͍ʁ ྫɿ     PL  PL

      OH    OH PL  PL   OH PL
  12. ྫ୊ $ऑ͘Β͍ʁ ྫɿ     PL  PL

      OH    OH PL  PL   OH PL  PL
  13. ྫ୊ $ऑ͘Β͍ʁ ྫɿ     PL  PL

      OH    OH PL  PL   OH PL  PL PL
  14. ྫ୊ $ऑ͘Β͍ʁ ྫɿ     PL  PL

      OH    OH PL  PL   OH PL  PL PL
  15. n = int(input()) a = input().split().map(int) max = 0 for

    from in range(0, n): for to in range(i, n): sum = 0 for i in range(from, to + 1): sum += a[i] if sum <= 100: if to – from + 1 > max: max = to – from + 1 print(max) #include <stdio.h> int main (void) { int n, a[300], i, from, to, max = 0; scanf(“%d”, &n); for (i = 0; i < n; i++) scanf(“%d”, &a[i]); for (from = 0; from < n; from++) for (to = sum = 0; to < n; to++) { for (i = from; i <= to; i++) sum += a[i] if (sum <= 100) if (to – from + 1 > max) max = to – from + 1; } printf(“%d¥n”, max); } 1ZUIPOͷྫ $ͷྫ
  16. ྦྷੵ࿨ \"<J>^    \4<J>^    

    ɾ΋ͱͷ਺ྻ "͔ΒɺҎԼͷΑ͏ʹʮྦྷੵ࿨ʯ4Λ࡞Δ ɾ4<J>ΛݟΔͱ "<>d"<J>·Ͱͷ૯࿨͕ҰܸͰΘ͔Δ
  17. ྦྷੵ࿨ \"<J>^    \4<J>^    

    ɾ΋ͱͷ਺ྻ "͔ΒɺҎԼͷΑ͏ʹʮྦྷੵ࿨ʯ4Λ࡞Δ ɾ4<J>ΛݟΔͱ "<>d"<J>·Ͱͷ૯࿨͕ҰܸͰΘ͔Δ ɾ"<J>d"<K>·Ͱͷ૯࿨͸ɺ 4<K >r 4<J>ͰΘ͔Δ
  18. ྦྷੵ࿨ \"<J>^    \4<J>^    

    ɾ΋ͱͷ਺ྻ "͔ΒɺҎԼͷΑ͏ʹʮྦྷੵ࿨ʯ4Λ࡞Δ ɾ4<J>ΛݟΔͱ "<>d"<J>·Ͱͷ૯࿨͕ҰܸͰΘ͔Δ ɾ"<J>d"<K>·Ͱͷ૯࿨͸ɺ 4<K > r 4<J>ͰΘ͔Δ
  19. ྦྷੵ࿨ \"<J>^    \4<J>^    

    ɾ΋ͱͷ਺ྻ "͔ΒɺҎԼͷΑ͏ʹʮྦྷੵ࿨ʯ4Λ࡞Δ ɾ4<J>ΛݟΔͱ "<>d"<J>·Ͱͷ૯࿨͕ҰܸͰΘ͔Δ ɾ"<J>d"<K>·Ͱͷ૯࿨͸ɺ 4<K > r 4<J> ͰΘ͔Δ
  20. ྫ୊ վೋ %͘Β͍ʁ  ɾ/ͱɺ /ݸͷ੔਺ "<>"</>͕༩͑ΒΕΔ ɾ૯࿨͕ ະຬͱͳΔ෦෼ྻͷ͏ͪ࠷௕ͷ΋ͷ͸Կཁૉ͔ ˞෦෼ྻ

    ʹ ਺ྻͷઌ಄ɾ຤ඌ͔Β ݸҎ্ͷཁૉΛࣺͯͨ΋ͷ ɾ/͸  ?  ?  ? ҎԼ
  21. 1SPKFDU&VMFSr .BYJNVNQBUITVN վ ɾࡾ֯ܗঢ়ʹฒΜͩ੔਺͕ ஈ༩͑ΒΕΔ ɾҰ൪্ͷ਺ࣈ͔ΒਅԼ PSӈԼΛ܁Γฦ͠બΜͰ߱Γ͍ͯ͘ ɾҰ൪૯࿨͕େ͖͘ͳΔϧʔτͷ૯࿨͸ʁ  

           
  22. 1SPKFDU&VMFSr .BYJNVNQBUITVN վ       

               ɾࡾ֯ܗঢ়ʹฒΜͩ੔਺͕ ஈ༩͑ΒΕΔ ɾҰ൪্ͷ਺ࣈ͔ΒਅԼ PSӈԼΛ܁Γฦ͠બΜͰ߱Γ͍ͯ͘ ɾҰ൪૯࿨͕େ͖͘ͳΔϧʔτͷ૯࿨͸ʁ
  23. 1SPKFDU&VMFSr .BYJNVNQBUITVN վ ɾࡾ֯ܗঢ়ʹฒΜͩ੔਺͕ ஈ༩͑ΒΕΔ ɾҰ൪্ͷ਺ࣈ͔ΒਅԼ PSӈԼΛ܁Γฦ͠બΜͰ߱Γ͍ͯ͘ ɾҰ൪૯࿨͕େ͖͘ͳΔϧʔτͷ૯࿨͸ʁ  

                    
  24. 1SPKFDU&VMFSr .BYJNVNQBUITVN վ ɾࡾ֯ܗঢ়ʹฒΜͩ੔਺͕ ஈ༩͑ΒΕΔ ɾҰ൪্ͷ਺ࣈ͔ΒਅԼ PSӈԼΛ܁Γฦ͠બΜͰ߱Γ͍ͯ͘ ɾҰ൪૯࿨͕େ͖͘ͳΔϧʔτͷ૯࿨͸ʁ  

           
  25. ෼ׂ౷࣏ ࠶ؼ ɾσΧࡾ֯Λ੨ࡾ֯ͱᒵࡾ֯ʹ෼͚Δ ˠ ͦΕͧΕ࠷ڧϧʔτΛܭࢉͯ͠ɺڧ͍ํʹ  ଍ͤ͹ PL  

                               
  26. ෼ׂ౷࣏ ࠶ؼ        

     ɾσΧࡾ֯Λ੨ࡾ֯ͱᒵࡾ֯ʹ෼͚Δ ˠ ͦΕͧΕ࠷ڧϧʔτΛܭࢉͯ͠ɺڧ͍ํʹ ଍ͤ͹ PL
  27. ෼ׂ౷࣏ ࠶ؼ        

                      ɾ͜ͷ෼ղ͸ԿճͰ΋܁ΓฦͤΔ ɾݶք·Ͱ܁Γฦ͢ͱɺΫι΄Ͳ؆୯ͳ໰୊ʹؼண͢Δ
  28. ෼ׂ౷࣏ ࠶ؼ        

    ɾ͜ͷ෼ղ͸ԿճͰ΋܁ΓฦͤΔ ɾݶք·Ͱ܁Γฦ͢ͱɺΫι΄Ͳ؆୯ͳ໰୊ʹؼண͢Δ
  29. ෼ׂ౷࣏ ࠶ؼ        

                    ɾ͜ͷ෼ղ͸ԿճͰ΋܁ΓฦͤΔ ɾݶք·Ͱ܁Γฦ͢ͱɺΫι΄Ͳ؆୯ͳ໰୊ʹؼண͢Δ
  30. ෼ׂ౷࣏ ࠶ؼ ɾϓϩάϥϜʹམͱ͠ࠐΉͱ͜Μͳײ͡ # y 段目 x 桁目から始まる三角形の最強を求める関数 def computeMaxRoute

    (x, y): # もしここが最下段だったら、数字は一つしかないのでそれが答え if y == 10: return a[x][y] else: # 二つの小さい三角形で問題を解いて、より強い方を取る leftMax = computeMaxRoute(x, y + 1) rightMax = computeMaxRoute(x + 1, y + 1) return max(leftMax, rightMax) + a[x][y]
  31. ෼ׂ౷࣏ ϝϞԽ ɾΞΠσΞɿॏෳͨ͠ܭࢉΛεΩοϓ͢Δ ˠ ࠶ؼͰొ৔͢Δࡾ֯ܗ͸͍͍ͤͥ O?छྨ͔͠ͳ͍    

         
  32. ෼ׂ౷࣏ ϝϞԽ ɾΞΠσΞɿॏෳͨ͠ܭࢉΛεΩοϓ͢Δ ˠ ࠶ؼͰొ৔͢Δࡾ֯ܗ͸͍͍ͤͥ O?छྨ͔͠ͳ͍    

          
  33. ෼ׂ౷࣏ ϝϞԽ ɾΞΠσΞɿॏෳͨ͠ܭࢉΛεΩοϓ͢Δ ˠ ࠶ؼͰొ৔͢Δࡾ֯ܗ͸͍͍ͤͥ O?छྨ͔͠ͳ͍    

                  
  34. ෼ׂ౷࣏ ϝϞԽ ɾΞΠσΞɿॏෳͨ͠ܭࢉΛεΩοϓ͢Δ ˠ ࠶ؼͰొ৔͢Δࡾ֯ܗ͸͍͍ͤͥ O?छྨ͔͠ͳ͍    

                   
  35. ෼ׂ౷࣏ ϝϞԽ ɾΞΠσΞɿॏෳͨ͠ܭࢉΛεΩοϓ͢Δ ˠ ࠶ؼͰొ৔͢Δࡾ֯ܗ͸͍͍ͤͥ O?छྨ͔͠ͳ͍    

                   
  36. ෼ׂ౷࣏ ϝϞԽ ɾΞΠσΞɿॏෳͨ͠ܭࢉΛεΩοϓ͢Δ ˠ ࠶ؼͰొ৔͢Δࡾ֯ܗ͸͍͍ͤͥ O?छྨ͔͠ͳ͍    

                          
  37. ෼ׂ౷࣏ ϝϞԽ ɾΞΠσΞɿॏෳͨ͠ܭࢉΛεΩοϓ͢Δ ˠ ࠶ؼͰొ৔͢Δࡾ֯ܗ͸͍͍ͤͥ O?छྨ͔͠ͳ͍    

                           
  38. ෼ׂ౷࣏ ϝϞԽ ɾΞΠσΞɿॏෳͨ͠ܭࢉΛεΩοϓ͢Δ ˠ ࠶ؼͰొ৔͢Δࡾ֯ܗ͸͍͍ͤͥ O?छྨ͔͠ͳ͍    

                           
  39. ෼ׂ౷࣏ ϝϞԽ ɾΞΠσΞɿॏෳͨ͠ܭࢉΛεΩοϓ͢Δ ˠ ࠶ؼͰొ৔͢Δࡾ֯ܗ͸͍͍ͤͥ O?छྨ͔͠ͳ͍    

                           
  40. ෼ׂ౷࣏ ϝϞԽ ɾΞΠσΞɿॏෳͨ͠ܭࢉΛεΩοϓ͢Δ ˠ ࠶ؼͰొ৔͢Δࡾ֯ܗ͸͍͍ͤͥ O?छྨ͔͠ͳ͍    

                                 
  41. ෼ׂ౷࣏ ϝϞԽ ɾϓϩάϥϜʹམͱ͠ࠐΉͱ͜Μͳײ͡ # -1 (未計算を表す) がぎっしり並んだ配列 memo = [([-1]

    * 1001) for i in range(1,1001)] def computeMaxRouteWithMemo (x, y): # まだ計算した事がなかった場合だけ計算 if memo[x][y] == -1: memo[x][y] = computeMaxRoute(x, y) return memo[x][y]
  42. ෼ׂ౷࣏ %1 ɾʮϝϞԽ࠶ؼΛԼ͔Β΍Δౕʯ       

                 ̍ஈ໨͸ͦͷ··ॻ͖ࣸ͢
  43. ෼ׂ౷࣏ %1 ɾʮϝϞԽ࠶ؼΛԼ͔Β΍Δౕʯ       

                    ਅԼ PSӈԼͷ͏ͪڧ͍ํʴࣗ਎ͷ਺ࣈ
  44. ෼ׂ౷࣏ %1 ɾʮϝϞԽ࠶ؼΛԼ͔Β΍Δౕʯ       

                     
  45. ෼ׂ౷࣏ %1 ɾʮϝϞԽ࠶ؼΛԼ͔Β΍Δౕʯ       

                        
  46. ෼ׂ౷࣏ %1 ɾʮϝϞԽ࠶ؼΛԼ͔Β΍Δౕʯ       

                    
  47. ෼ׂ౷࣏ %1 ɾʮϝϞԽ࠶ؼΛԼ͔Β΍Δౕʯ       

                   
  48. ෼ׂ౷࣏ %1 ɾʮϝϞԽ࠶ؼΛԼ͔Β΍Δౕʯ       

                   
  49. ෼ׂ౷࣏ %1 ɾʮϝϞԽ࠶ؼΛԼ͔Β΍Δౕʯ       

       Y