สิ่งที่น่าพิศวงน่าพิศวง


9

สิ่งที่น่าพิศวงเป็นเกมบาสเกตบอลที่ผู้เล่นผลัดกันยิง มันถูกเล่นเป็นลำดับของการแข่งขันสำหรับผู้เล่นสองคนโดยแต่ละคนมีความเป็นไปได้ที่จะ "เตะออก" หนึ่งในผู้เล่นเหล่านั้น

สมมติว่าผู้เล่นมีA B C Dโอกาสในการยิงและจัดทำตะกร้า0.1 0.2 0.3 0.4ตามลำดับโดยไม่ขึ้นกับผู้เล่นอื่นในการแข่งขัน ผู้เล่นสองคนที่อยู่ด้านหน้าของแถวAและB"ต่อสู้" ตั้งแต่Aไปก่อนเขาเป็นผู้พิทักษ์ตกอยู่ในอันตรายจากการถูกกำจัดและBเป็นผู้โจมตีและไม่ตกอยู่ในอันตรายจากการกำจัดทันที Aถ่ายภาพก่อน ถ้าAทำให้Aสำเร็จป้องกันได้สำเร็จและไปที่ด้านหลังของบรรทัด B C D Aสายจะเปลี่ยนไป ถ้าAไม่ทำก็ให้Bยิง ถ้าBทำแล้วAจะออกและไปที่หลังของบรรทัดเพื่อให้กลายเป็นเส้นB C D Bถ้าไม่AหรือBทำให้เป็นกระบวนการซ้ำด้วยการAยิงอีกครั้งจนกระทั่งAหรือBทำตะกร้า

สมมติว่าบรรทัดเปลี่ยนเป็นB C D A( Aเคยป้องกันได้สำเร็จ) ตอนนี้BและC"ต่อสู้" ด้วยBการเป็นผู้พิทักษ์และCเป็นผู้โจมตี กระบวนการนี้ทำซ้ำจนกว่าจะเหลือเพียงคนเดียวเท่านั้น บุคคลนั้นเป็นผู้ชนะ

งานของคุณคือการคำนวณความน่าจะเป็นของผู้ชนะแต่ละคนที่ได้รับโอกาสที่จะทำตะกร้า

อินพุต :

รายการของตัวเลขเช่น0.1 0.2หรือ0.5 0.5 0.5 0.5ที่ซึ่งหมายเลขnเป็นโอกาสที่ผู้เล่นที่nจะทำตะกร้า คุณสามารถรับอินพุตนี้ในรูปแบบใดก็ได้ที่คุณต้องการรวมถึงเป็นพารามิเตอร์ในฟังก์ชัน

ผลผลิต :

รายชื่อหมายเลขที่หมายเลขnเป็นโอกาสที่ผู้เล่นที่nจะชนะเกม หมายเลขของคุณจะต้องแม่นยำอย่างน้อยสองตำแหน่งทศนิยมอย่างน้อย 90% ของเวลา ซึ่งหมายความว่าคุณสามารถใช้วิธีการจำลองตาม อย่างไรก็ตามหากรหัสของคุณไม่ได้เป็นแบบจำลอง ( รับประกันว่าจะคืนคำตอบที่ถูกต้องให้กับตำแหน่งทศนิยมอย่างน้อย 6 ตำแหน่ง) จากนั้นให้ลด 30% จากคะแนนของคุณ

ตัวอย่างระหว่าง0.5 0.5: เรียกผู้เล่นและA Bอนุญาตpเป็นความน่าจะเป็นของการชนะ Aมี2/3โอกาสประสบความสำเร็จในการป้องกัน (เนื่องจากมี1/2โอกาสที่จะAทำคะแนน, 1/4โอกาสที่AพลาดและBทำคะแนน, และ1/4โอกาสที่ทั้งพลาดและทำซ้ำ) หากAล้มเหลวในการปกป้องเขาจะถูกกระแทกและBชนะ หากปกป้องแล้วสายจะกลายเป็นA B Aเนื่องจากสถานการณ์เป็นสมมาตรความน่าจะเป็นของการชนะคือA (1 - p)เราได้รับ:

p = 2/3 * (1 - p) + 1/3 * 0. p = 2/5แก้ที่เราได้รับ เอาท์พุทควรจะเป็นหรือ2/5 3/50.4 0.6

ฉันไม่ดีพอที่มีความเป็นไปได้ที่จะทำตัวอย่างที่ซับซ้อนมากขึ้น

หากคุณต้องการกรณีทดสอบเพิ่มเติมนี่คือตัวอย่าง:

0.1 0.2 0.3 0.4 --> 0.01 0.12 0.25 0.62
0.99 0.99 --> 0.5 0.5 (it's not exact, but if you round to two decimal places, you get 0.5 and 0.5)

คำตอบ:


4

CJam ( 84 80 ตัวอักษร * 0.7 = 56)

{_,({_,,{_2$m<(;(+Q0\)\++m>\}%)_(+.{X2$-*_@+/}1\{1$*\1$-}%)1\-f/.f*:.+}{,da}?}:Q

สาธิตออนไลน์ นี่คือฟังก์ชั่นวนซ้ำซึ่งใช้อาเรย์เป็นสองเท่าและส่งกลับอาเรย์เป็นสองเท่า การสาธิตออนไลน์รวมถึงการนั่งร้านจำนวนเล็กน้อยเพื่อใช้งานฟังก์ชั่นและจัดรูปแบบเอาต์พุตสำหรับการแสดงผล

การผ่า

หลักการพื้นฐานคือถ้ามีn > 1ผู้เล่นเหลืออยู่หนึ่งในนั้นจะต้องเป็นคนต่อไปที่จะทำให้ล้มลง ยิ่งไปกว่านั้นลำดับของคิวที่เกิดขึ้นนั้นขึ้นอยู่กับลำดับเริ่มต้นของคิวและผู้ที่ได้รับการกระแทกเท่านั้น ดังนั้นเราสามารถทำการnโทรซ้ำคำนวณความน่าจะเป็นที่ชนะสำหรับผู้เล่นแต่ละคนในแต่ละกรณีและจากนั้นเราต้องเพิ่มน้ำหนักอย่างเหมาะสมและเพิ่ม

[p_0 p_1 ... p_{n-1}]ฉันจะป้ายความน่าจะเป็นการป้อนข้อมูลที่เป็น ขอf(a,b)แสดงว่าน่าจะเป็นที่ล้มเหลวในการป้องกันa bในรอบใดก็ตามน่าจะเป็นที่aปกป้องประสบความสำเร็จเป็นที่p_aน่าจะเป็นที่bเคาะaออกมาเป็นและความน่าจะเป็นว่ามันจะไปอีกรอบเป็น(1-p_a)*p_b (1-p_a)*(1-p_b)เราสามารถทำผลรวมที่ชัดเจนของความก้าวหน้าทางเรขาคณิตหรือเราสามารถยืนยันได้ว่าทั้งสองการก้าวหน้าเรขาคณิตเป็นสัดส่วนกับแต่ละอื่น ๆ f(a,b) = (1-p_a)*p_b / (p_a + (1-p_a)*p_b)ที่จะด้วยเหตุผลที่ว่า

จากนั้นเราสามารถเพิ่มระดับเป็นรอบเต็มของบรรทัด ความน่าจะเป็นที่ผู้เล่นคนแรกถูกเขี่ยออกไปคือf(0,1); ความน่าจะเป็นที่ผู้เล่นคนที่สองถูกเขี่ยออกไปคือ(1-f(0,1)) * f(1,2); ผู้เล่นที่สามคือ(1-f(0,1)) * (1-f(1,2)) * f(2,3); ฯลฯ จนกระทั่งคนสุดท้ายถูกทำให้ล้มลงด้วยความน่าจะ\prod_i (1-f(i,i+1)) * f(n-1,0)เป็น 1 / \prod_i f(i, i+1 mod n)อาร์กิวเมนต์เหมือนกันเกี่ยวกับการก้าวหน้าเรขาคณิตช่วยให้เราสามารถใช้ความน่าจะเป็นเหล่านี้เป็นน้ำหนักกับการฟื้นฟูโดยปัจจัยของ

{                   e# Define a recursive function Q
  _,({              e# If we have more than one person left in the line...
    _,,{            e#   Map each i from 0 to n-1...
      _2$m<         e#     Rotate a copy of the probabilities left i times to get [p_i p_{i+1} ... p_{n-1} p_0 ... p_{i-1}]
      (;(+          e#     i fails to defend, leaving the line as [p_{i+2} ... p_{n-1} p_0 ... p_{i-1} p_{i+1}]
      Q             e#     Recursive call
      0\)\++        e#     Insert 0 for the probability of i winning and fix up the order
      m>\           e#     Rotate right i times and push under the list of probabilities
    }%
    )               e#   Stack: [probs if 0 knocked out, probs if 1 knocked out, ...] [p_0 p_1 ...]
    _(+.{           e#   Duplicate probs, rotate 1, and pointwise map block which calculates f(a,b)
      X2$-*_@+/     e#     f(a,b) = (1-p_a)*p_b / (p_a + (1-p_a)*p_b)  TODO is the d necessary?
    }
    1\{1$*\1$-}%    e#   Lift over the list of f(a,b) a cumulative product to get the weights  TODO is the d necessary?
    )1\-f/          e#   Normalise the weights
    .f*             e#   Pointwise map a multiplication of the probabilities for each case with the corresponding weight
    :.+             e#   Add the weights across the cases
  }{,da}?           e# ...else only one left, so return [1.0]
}:Q
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.