Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

กบกระโดดใน C++


สมมุติว่ามีกบกำลังข้ามแม่น้ำ แม่น้ำแบ่งออกเป็น x หน่วย และแต่ละหน่วยอาจมีหิน กบกระโดดบนหินได้ แต่ไม่สามารถกระโดดน้ำได้ เรามีรายชื่อตำแหน่งของหินที่เรียงจากน้อยไปมาก เราต้องตรวจสอบว่ากบสามารถข้ามแม่น้ำโดยการลงจอดบนหินก้อนสุดท้ายได้หรือไม่ ในขั้นต้น กบอยู่บนก้อนหินก้อนแรก และถือว่าการกระโดดครั้งแรกต้องมี 1 หน่วย

เมื่อกบกระโดดในปัจจุบันคือ k หน่วย การกระโดดครั้งต่อไปต้องเป็น k - 1, k หรือ k + 1 หน่วย และกบสามารถกระโดดไปข้างหน้าได้เท่านั้น

ดังนั้นหากอาร์เรย์ที่กำหนดเป็น [0,1,3,4,5,7,9,10,12] คำตอบจะเป็นจริงเช่น กบสามารถกระโดดไปที่หินก้อนที่ 1 ถึงก้อนที่ 2 และ 2 หน่วยไปที่ หินที่ 3 จากนั้นอีก 2 หน่วยไปยังหินที่ 4 จากนั้น 3 หน่วยถึงหินที่ 6, 4 หน่วยถึงหินที่ 7 และสุดท้าย 5 หน่วยถึงหินที่ 8

เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -

  • กำหนดแผนที่เรียกว่าเยี่ยมชมแล้ว
  • กำหนดฟังก์ชัน canCross() ซึ่งจะใช้อาร์เรย์สโตน pos เริ่มต้นด้วย 0, k เริ่มต้นด้วย 0,
  • คีย์ :=pos OR (กะซ้าย k 11 บิต)
  • ถ้ามีคีย์อยู่ในการเยี่ยมชมแล้ว −
    • กลับมาเยี่ยมชม[คีย์]
  • สำหรับการเริ่มต้น i :=pos + 1 เมื่อฉัน <ขนาดของก้อนหิน อัปเดต (เพิ่ม i ขึ้น 1) ทำ −
    • ช่องว่าง:=หิน[i] - หิน[pos]
    • ถ้าช่องว่าง
    • ไม่ต้องสนใจตอนต่อไป ข้ามไปที่ตอนต่อไป
  • ถ้าช่องว่าง> k + 1 แล้ว −
    • เข้าชมแล้ว[คีย์] :=false
    • คืนค่าเท็จ
  • ถ้าเรียกใช้ฟังก์ชัน canCross(stones, i, gap) ไม่ใช่ศูนย์ ดังนั้น −
    • เข้าชมแล้ว[คีย์] =จริง
    • คืนค่าจริง
  • เยี่ยมชม[คีย์] =จริง เมื่อ (ตำแหน่งเท่ากับขนาดของก้อนหิน - 1) มิฉะนั้น เท็จ
  • กลับมาเยี่ยมชม[คีย์]
  • ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -

    ตัวอย่าง

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long int lli;
    class Solution {
    public:
       unordered_map < lli, int > visited;
       bool canCross(vector<int>& stones, int pos = 0, int k = 0) {
          lli key = pos | k << 11;
          if(visited.find(key) != visited.end())return visited[key];
          for(int i = pos + 1; i < stones.size(); i++){
             int gap = stones[i] - stones[pos];
             if(gap < k - 1)continue;
             if(gap > k + 1){
                return visited[key] = false;
             }
             if(canCross(stones, i, gap))return visited[key] = true;
          }
          return visited[key] = (pos == stones.size() - 1);
       }
    };
    main(){
       Solution ob;
       vector<int> v = {0,1,3,5,6,8,12,17};
       cout << (ob.canCross(v));
    }

    อินพุต

    0,1,3,5,6,8,12,17

    ผลลัพธ์

    1