Frogger Champion


11

เกม

พวกเราส่วนใหญ่รู้เกี่ยวกับFroggerเกมอาร์เคดยุค 80 ที่มีวัตถุประสงค์เพื่อกระโดดกบอย่างปลอดภัยบนทางหลวงที่พลุกพล่านและบ่อที่เต็มไปด้วยอันตรายเพื่อมาถึงที่บ้านอย่างปลอดภัย

มีการออกความท้าทายเมื่อหลายเดือนก่อนเพื่อพัฒนาโคลนนิ่งของ Frogger แต่ทำไมต้องโคลนนิ่ง Frogger เมื่อคุณสามารถเล่น Frogger ได้? :)

พิจารณาตารางการเล่นที่ง่ายขึ้นดังต่อไปนี้:

 XXXXXXXXXXXXXXXXXXXXXXX  North Safe Zone
 -----------------------
|                       | <<<<       Express Lane West        (Lane 1)
|                       |     >      Gridlock East            (Lane 2)
|                       |   <<       Freeflowing Traffic West (Lane 3)
|                       |    <       Gridlock West            (Lane 4)
|                       |     >>>>   Express Lane East        (Lane 5)
 -----------------------
 XXXXXXXXXXX@XXXXXXXXXXX  South Safe Zone
 \__________ __________/
            '
  23 cells horizontally

เรามีช่องทางจราจรห้าเลนกว้าง 23 เซลล์แต่ละแห่งและโซนปลอดภัยสองแห่ง (ที่กบสามารถเคลื่อนที่ไปทางซ้ายและขวาอย่างปลอดภัย) และอีก 23 เซลล์กว้าง คุณอาจเพิกเฉยต่อขอบด้านซ้ายและขวาเนื่องจากสิ่งเหล่านี้มีไว้เพื่อภาพที่ชัดเจน

กบของเราเริ่มต้นในเขตปลอดภัยทางใต้ในเซลล์กลาง (อันดับที่ 12) ตามที่ระบุ@ในรูปด้านบน

เวลาในเกมแบ่งออกเป็นขั้นตอนไม่ต่อเนื่องที่เรียกว่าเฟรม Froggy เป็นกบที่รวดเร็วและสามารถกระโดดหนึ่งเซลล์ในทิศทางใดก็ได้ (ขึ้น, ลง, ขวา, ซ้าย) ต่อเฟรม เขาอาจเลือกที่จะอยู่นิ่งกับเฟรมใดก็ได้ การจราจรในห้าเลนจะเคลื่อนที่ด้วยความเร็วคงที่ดังต่อไปนี้:

  • การจราจรในช่องทางด่วนตะวันตก (เลน 1) ย้าย 2 เซลล์ออกจากทุกเฟรม
  • การจราจรใน gridlock east lane (เลน 2) เลื่อน 1 เซลล์ไปทางขวาทุก ๆ เฟรมที่สอง
  • การจราจรในช่องจราจรทางตะวันตกที่ไหลเยือก (ช่อง 3) เลื่อน 1 เซลล์ออกจากทุกเฟรม
  • การจราจรใน gridlock west lane (เลน 4) ย้าย 1 เซลล์ไปทางซ้ายทุกเฟรมที่สอง
  • การจราจรในช่องทางด่วนตะวันออก (เลน 5) เลื่อน 2 เซลล์ไปทางขวาทุกเฟรม

การจราจรนั้นถูกกำหนดโดยไม่ซ้ำกันประมาณ 3,000 timesteps ในไฟล์ข้อความนี้ 'การจราจร' ประกอบด้วยยานพาหนะและช่องว่างระหว่างยานพาหนะ ตัวละครที่ไม่ได้เว้นวรรคนั้นเป็นส่วนหนึ่งของยานพาหนะ ไฟล์ข้อความมีห้าบรรทัดซึ่งสอดคล้องกับห้าเลนของการรับส่งข้อมูล (ที่มีลำดับเดียวกัน)

สำหรับเลนฝั่งตะวันตกที่จุดเริ่มต้นของเฟรม 0 (เริ่มเกม) เราพิจารณารถคันแรกในเลนนั้นเกินขอบด้านขวาของกริดการเล่น

สำหรับเลนทางทิศตะวันออกสตริงการจราจรควรได้รับการพิจารณาว่า "ย้อนกลับ" ในแง่ที่ว่ายานพาหนะนั้นเริ่มต้นที่จุดสิ้นสุดของสตริง ที่จุดเริ่มต้นของเฟรม 0 เราถือว่ารถคันแรกในเลนเหล่านี้อยู่เหนือขอบด้านซ้ายของสนามเด็กเล่น

พิจารณาเป็นตัวอย่าง:

Traffic Lane 1:  [|==|  =
Traffic Lane 2:  |) =  o
Traffic Lane 3:  (|[]-[]:
Traffic Lane 4:  <| (oo|
Traffic Lane 5:  |==|] :=)

จากนั้นตารางการเล่นจะปรากฏดังนี้:

Start of Frame 0       XXXXXXXXXXXXXXXXXXXXXXX
                                              [|==|  =
                |) =  o
                                              (|[]-[]:
                                              <| (oo|
              |==|] :=)
                       XXXXXXXXXXXXXXXXXXXXXXX

Start of Frame 1       XXXXXXXXXXXXXXXXXXXXXXX
                                            [|==|  =
                |) =  o
                                             (|[]-[]:
                                              <| (oo|
                |==|] :=)
                       XXXXXXXXXXXXXXXXXXXXXXX

Start of Frame 2       XXXXXXXXXXXXXXXXXXXXXXX
                                          [|==|  =
                 |) =  o
                                            (|[]-[]:
                                             <| (oo|
                  |==|] :=)
                       XXXXXXXXXXXXXXXXXXXXXXX

Start of Frame 3       XXXXXXXXXXXXXXXXXXXXXXX
                                        [|==|  =
                 |) =  o
                                           (|[]-[]:
                                             <| (oo|
                    |==|] :=)
                       XXXXXXXXXXXXXXXXXXXXXXX

หลังจากการรับส่งข้อมูลทั้งหมดในเลนคือ "พร่อง" (เช่นสตริงหมด) เราจะพิจารณาอักขระทั้งหมดในสตริงเป็นช่องว่าง

กบของเราถูกแบนหากมีสิ่งใดสิ่งหนึ่งต่อไปนี้เกิดขึ้น:

  • กบครอบครองเซลล์ที่ยานพาหนะครอบครองอยู่บนเฟรมใด ๆ
  • กบยังคงอยู่กับที่ในเลนด่วนและยานพาหนะที่มีความกว้าง 1 เซลล์ผ่านเขาไปในเฟรมนั้น
  • กบกระโดดไปทางตะวันออก "ผ่าน" ยานพาหนะที่มุ่งหน้าไปทางทิศตะวันตกหรือกระโดดไปทางทิศตะวันตกผ่านยานพาหนะที่มุ่งไปทางตะวันออก
  • กบกระโดดออกไปข้างนอก 7 (บรรทัด) โดย 23 (เซลล์) เล่นกริดในกรอบใด ๆ

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

วัตถุประสงค์และเกณฑ์การให้คะแนน

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

ผลลัพธ์ของโปรแกรมของคุณควรเป็นสตริง (หรือไฟล์ข้อความ) ที่มีลำดับการเคลื่อนไหวสำหรับกบโดยใช้การเข้ารหัสต่อไปนี้:

<   frog moves left
>   frog moves right
^   frog moves up
v   frog moves down
.   frog remains stationary

ตัวอย่างเช่นสตริง<<^.^ระบุว่ากบเลื่อนไปทางซ้ายสองครั้งจากนั้นขึ้นแล้วหยุดชั่วขณะหนึ่งเฟรมจากนั้นเลื่อนขึ้นอีกครั้ง

มีการให้คะแนนหนึ่งคะแนนเมื่อกบข้ามจากเขตปลอดภัยใต้ไปยังโซนปลอดภัยเหนือและหนึ่งคะแนนจะถูกทำคะแนนเมื่อกบข้ามจากโซนปลอดภัยเหนือไปยังโซนเซฟใต้

กฎที่สำคัญบางประการ:

  1. กบจะต้องไม่ถูกบีบ
  2. กรุณาโพสต์วิธีแก้ปัญหาของคุณ (ลำดับของการเคลื่อนไหว) พร้อมกับรหัสโปรแกรมของคุณทั้งแบบอินไลน์หรือเป็นไฟล์ข้อความ (เช่นการใช้ pastebin.com)
  3. กบของเรานั้นมีสติและไม่สามารถจดจำได้ดังนั้นโปรแกรมของคุณอาจใช้ข้อมูลการจราจรใด ๆ ก็ตามในทุกเฟรมในขณะที่หาวิธีแก้ปัญหา ซึ่งรวมถึงข้อมูลสำหรับการรับส่งข้อมูลที่ยังไม่ถึงตารางการเล่น
  4. กริดไม่พันกัน การออกจากกริดจะทำให้กบถูกแบนและด้วยเหตุนี้จึงไม่ได้รับอนุญาต
  5. การรับส่งข้อมูลจะไม่มีการ "รีเซ็ต" หรือกบ "เทเลพอร์ต" การจำลองอย่างต่อเนื่อง
  6. กบอาจกลับไปยังเขตปลอดภัยทางใต้หลังจากออกไป แต่สิ่งนี้ไม่นับเป็นจุด เช่นเดียวกันสำหรับเขตปลอดภัยเหนือ
  7. ผู้ชนะการประกวดคือโปรแกรมที่สร้างลำดับการเคลื่อนย้ายที่ให้จำนวนการข้ามสูงสุด
  8. สำหรับคำถามหรือข้อสงสัยเพิ่มเติมโปรดอย่าลังเลที่จะถามในส่วนความเห็น

สำหรับสิ่งที่เพิ่มเข้ามาฉันจะเพิ่มค่าตอบแทน+100 ตัวแทนให้กับโปรแกรมที่ชนะเมื่อฉันสามารถทำได้

โบนัส

+ 2.5%ไปยังคะแนนฐาน * (สูงถึง + 10%) สำหรับทุกมุมของตารางการเล่นที่สัมผัสกับกบ มุมทั้งสี่ของกริดเป็นเซลล์ด้านซ้ายและขวาของโซนปลอดภัยสองโซน

+ 25%ไปยังคะแนนฐาน * หากลำดับการเคลื่อนไหวของคุณเก็บกบไว้ใน +/- 4 เซลล์ทางซ้ายหรือขวาของเซลล์เริ่มต้นสำหรับการจำลองทั้งหมด (แน่นอนว่าเขาสามารถเคลื่อนไหวได้อย่างอิสระในแนวตั้ง)

ไม่มีโบนัสให้คะแนน แต่อุปกรณ์ประกอบฉากพิเศษใน OP จะไปถึงทุกคนที่โพสต์เครื่องมือตรวจสอบความถูกต้องของวิธีแก้ปัญหาอย่างรวดเร็วเพื่อที่ฉันจะได้ไม่ต้องตั้งโปรแกรม ;) เครื่องมือตรวจสอบจะยอมรับลำดับของการเคลื่อนไหวให้แน่ใจว่าถูกต้องตามกฎหมาย (ตามกฎและไฟล์การรับส่งข้อมูล) และรายงานคะแนน (เช่นจำนวนรวมของการข้าม)

* คะแนนรวมเท่ากับคะแนนฐานบวกโบนัสปัดเศษเป็นจำนวนเต็มที่ใกล้เคียงที่สุด

ขอให้โชคดี!


ให้กับทุกคนที่ต้องการที่จะแสดงความตรวจสอบการแก้ปัญหา: กรุณาอย่าโพสต์เป็นคำตอบ
Geobits

จริง ลิงค์ไปยังรหัสในความคิดเห็นหรือเป็นภาคผนวกของการแก้ไขจะเป็นวิธีที่ต้องการส่งตัวตรวจสอบ
COTO

เฟรมแรกที่เลนสปีดช้านั้นจะเหมือนกับเฟรมแรกที่เลนอื่นเลื่อนไปหรือเฟรมใดเฟรมหนึ่งในภายหลัง
feersum

นอกจากนี้ยังเป็นไปได้ที่จะทำคะแนนโดยไปถึง endzone ในเฟรมแรกที่รถยนต์ทุกคันได้ทำการล้างสนาม
feersum

@feersum: เลนช้าจะเลื่อนหนึ่งเฟรมในภายหลัง พวกเขายังคงไม่ขยับเขยื้อนในเฟรมแรกดังที่ระบุไว้ในตัวอย่าง สำหรับการให้คะแนนกบในเฟรมสุดท้าย: ใช่มันเป็นไปได้ หากกบได้ย้ายเข้าไปในเขตปลอดภัยบนเฟรมเดียวกันกับที่ยานพาหนะคันสุดท้ายออกจากสนามแข่งขันจะมีการทำแต้มหนึ่งแต้ม
COTO

คำตอบ:


5

C ++: 176

เอาท์พุท:

176
^^^^^^>vvvvvv>^^^^>^^>>>>>>><<<.vv>v<<<.vvv<<<<<<^.^.^.^.>.>^^<.>>>>>>v>v>.>v<<<<v.<.vv<<<<<^^.<^<<<<<<^.^^>>>>vv>.>.v<v.vv>>^>>^<^<<<<<<<^>.>^^<<<.>>>>>vv>v<vvv<<<<<^^.<^^^^.....vv>.>.>.>v<<vvv<<>>>>^>^<.<.^^>^^>>>>vv.>v<vv.v^>^<.<.<^<^>.>^^>>>>vv.v<<<<<<.vvv<<<<^^^<<v^^.>.^^..>>>>>>vv>.>.v.vvv>>>^>^^<<<<<<<<<^>.>^^>>>>vvv<<v.<.vv<<<<<<>>>>>^^^<<<^^^<<>>vv>.v<<>vvv<<><>>>>>>>^>^^<^^^<.>>>>>>>>vv>.>v<<<vvv<<<<<^^^<<v.<.<^<<^.^<<^...>>>>>>>>>>>>>vv>v<vvv<<<<<<<<^>^.<.^^>.>^^<<<<<<<..>>>>vv>.vvvv<<<<>^.v>>>^^.^^>^<^<>>>>>>>>>vv>vvvv<<<<^^^<^>^<<^.>>vv>v<vvv<<<<<<<>>>>>>>^>^^^.^^>>>>>vvv<<vvv<<<^^^^^^<vvv<<<<<<<vvv<<<>>>>>>>>^^.<.<.^.^.^<^<>>>>>>>>>>vvv<<.vvv<<<^^<^<<^^<<^<<<>>>>vv>.vvvv>>^>>^<.<.<^<<<<<.^^<<^.......>vv.>.>.>v<vvv>>>>>>^>^.<.<^<.^^^<.>>>>>>>vvv<<<v.<vv<<<^^<.<.<.<^<<<^>^^..........v<vvvv>v>>>>>^>>^^^>^^>>>vv>v<vvv<<<<<<<<>^^.<.<^<^^^<.........>vv.>.vvvv>>>>^^<.<.<^^^<^<<.v<v>.>.>.>.>.>.>.vvv.v<<<<<^^<^<^>.>.>.>.^<^.>>>>>>>>vv>v<<vvv<<>>>>>^^^.^.>^<^<<<<<<<<.vv.>.v<<<.vvv<>>>>>^>^.<.<.<.<^^.^<<^<.....>>vvv<.>>vvv<<<>>>>>>>>^^^<<<.^.>.>^^.>>>>>vv.>v<vvv<<<>>>>>>^>^<^<<^.^^<vvv<<<<<vv.v<>>>>>>>>>>^>^.^^>^^<<<<.>vv.>.vvvv>^>>^.<.<.<^<<<^>^^>>>vv>v<<<<<vvv<<<>>>>>^^<.<.<.<.<^<^>.^^.>>>>>vv>v<>vvv<<<<<<<^>^.<^<<<<<<<^^^.>>>>>vv>v<>vvv>>>^^<.<^<<<^>^^.>>>>vv>.v<<vvv<<<<<^^^<<<<<^>.^^<>>>>>>>vv>.>v<<vvv<<<<<<<>>>^>>.>^^^.>^^<>>>>>>vv>vv.<.<.vv>>>>^^<.<.<.<^<<^.>^^.>>>>>vv.>.>v<<vvv<<>>>>>^^<.<.<.^^>.>.>^^<<<<<<<<.>>>>>>vv>v<<v.<.<vv<<<<^^.<^<<<.^^^<.vv.>v<vvv<<<>>>>>>^>^<^<<^.^<^<<.>>vv>.>.>.>vvvv>>>>>>^>^^^^^<<<.vvv<<<<<<vvv>>>>>^>^<.<^<<^.>.>.^^>>>>vv>.>v<<<<<<vvv<<<<^^^<.^.>^^>>>>vvv<<v.vv<<<^>>^^<<<.^^<<^>>>>>>>>>vvv.v.vv<>>>>>^>^^<<<<<<<<<<<<<<<<^^^..>>>>>vv>.>.>.>v<<v.<.<.vv<<<<<^^^<^>.^^...>>>>>>>>vv.v<.vvv>>>^>^<.<^^^^>>>vv>v<<<vvv<<<<>>>>>>^>^.<.<^<^>.>^^.>>>>>vv.v<<<<<<<<vvv<<<<^^<^<<<<<><^>.>^^>>>>vv.>.>.vvv.v>>>>>>>^^<.<^<<^^^>>>vv>.>.>.>.>v<<v.<.<vv>>>>^^^<<<<<.^.>^^>>>vv>.>v<vvv<<<<^^<.<.<.^^>^^>>>vv>.>.v<<<v.<vv<<<<^^.<^<<<^^^>>>>vvvvvv<<<<<<<<>^^.^>>^^^<>>>>>>>vvv<<<v.vv>>>>>^>>^^<<<<<^>.^^>>>>vv>.>v<<<<vvv<<<^^<.<.<.<^<<<<<^>^^>>>>vv.>vv.v.v<^>.>^.<.^^^^>>>>vv>.>.>.v<<<<<<vvv>>>>^^<.<.<^<<^^<^>>>>>>vv>v<<.vvv^>^^<<<^>^^<<<<<<.vvv<<vv>.v>>>>>>^>.>^^<<<<<^>.>.>.>.>.^^>>>>vv>.>.>v<<<<<vvv<<<<^^<^<<^.^^>>>>vv>.>.>.>v<vvv<<<<<^^.<.<^<<^^^>>>>>>>>>>>vv>.>.>.>.>vvvv<<<<^^.<.<^<^^^<<<<<<vvv<v.<vv<<<<^v>>>>>>>>>>^^^<.^.>.>.^^>>>>vvv<<<<<<<vvv<<<<<<<>^^.<^<.^^^.>>>>vv>v<vvv<>>>>^^.<.^.^.>.^<^>>>>>>>>vvvv.<.<vv<<<<^^^<<<<<^>.^^<.vv>.v<<vvv<<><>>>>>^>>^.<^<^^^<<<.>>vv>.>v<<<<v.vv>^>>^.<^^.^^.>>>>>vv>.>.>.v<v.<vv<<<<<^.^^^.>^^<>>>>>>vv>.v<<<v.<vv<<<<>>>>>>>>>>>^^<.<.<.<.<^<<^^<^<<<>>>>>>>vv>v<<<vv.v>>>>>>>>^>^<.<^<<<<<<<<<<<.^.>^^<<<vvv.v.<vv<<<^.>>^.<^^.>.>^^<<......vv.v>vvv>>>^.v^>>^^<<^^^<.>>>>>>>vvv<v.<.<.vv<<<<^^<.<.<.^^^^<.>>>>>>>>vvv<v.<vv^.>^^<<^^^vv>vvvv^>>>>>>>^^^^^vvvvvv^^^^^^vvvvvv>>>>

มีการรวมสถานะต่ำกว่า 8 ล้านสถานะของตำแหน่ง X เวลา X ของมุมเข้าชมดังนั้นพวกเขาจึงสามารถค้นหาอย่างละเอียดภายในเวลาน้อยกว่า 1 วินาที หากรหัสไม่มีข้อบกพร่องมันเป็นไปไม่ได้ที่จะเอาชนะ กลยุทธ์ที่ดีที่สุดคือการใช้กระดานทั้งหมดเนื่องจากกบสามารถข้ามถนนได้ 160 ครั้งเทียบกับ 120 เมื่อถูกกักตัวไว้ที่กึ่งกลาง การไปที่มุมนั้นไม่ได้มีค่าใช้จ่ายใด ๆ เนื่องจากการจราจรคับคั่ง

/* feersum  2014/9
 /codegolf/37975/frogger-champion */

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <cstring>

#define B(F, CST, X, Y) best[ ((F)*NCST + (CST)) * BS + (Xmax-Xmin+1) * ((Y)-Ymin) + (X)-Xmin]
#define TL(i) ((int)t[i].length())
#define ABSPEED(I) (speed[i]<0?-speed[i]:speed[i])
#define errr(X) { cout<<"ERROR!!!!!!!!"; return X; }

#define DRAW 0
#if DRAW
    #include <unistd.h>
#endif


using namespace std;

int bc(int cs) {
    int c = 0;
    while(cs) {
        c += cs&1;
        cs >>= 1;
    }
    return c;
}

int main()
{
    const bool bonusTwentyfive = false;
    const int COLS = 23, T_ROWS = 5, YGS = T_ROWS + 2, XGS = COLS + 2;
    string t[5];
    int speed[] = {-4, 1, -2, -1, 4};
    ifstream f("t.txt");
    for(int i = 0; i < T_ROWS; i++)
        getline(f, t[i]);
    if(f.fail())
        return 1;
    f.close();
//for(int i = 0; i < 5; i ++)t[i]="xxx";

    char g[XGS][YGS];

    int mov[][3] = { {-1,  0, '<'},
                     {+1,  0, '>'},
                     { 0, -1, '^'},
                     { 0, +1, 'v'},
                     { 0,  0, '.'} };


    int Ymin = 0, Ymax = YGS-1;


    const int Xstart = 11, Xmaxmove = bonusTwentyfive ? 4 : 10;
    const int Xmin = Xstart - Xmaxmove, Xmax = Xstart + Xmaxmove;

    const int NCST = bonusTwentyfive ? 1 : 1<<4;

    int maxfr = 0;
    for(int i = 0; i < T_ROWS; i++) {
        if(speed[i] < 0) {
            for(int m = 0, n = t[i].length()-1; m < n; ++m,--n)
                swap(t[i][m], t[i][n]);
        }
        int carslen = TL(i);
        for(char*c = &t[i][speed[i]>0?TL(i)-1:0]; carslen; carslen--, speed[i]>0?--c:++c)
            if(*c != ' ')
                break;
        if(carslen)
            maxfr = max(maxfr, ( (carslen + COLS) * 2 + ABSPEED(i)-1 ) / ABSPEED(i));
    }
    const int BS = (Xmax-Xmin+1)*(Ymax-Ymin+1);
    int *best = new int[(maxfr+1)*NCST*BS];
    memset(best, 0xFF, (maxfr+1)*NCST*BS*sizeof(int));
    memset(g, ' ', sizeof(g));
    B(0, 0, Xstart, Ymax) = 0;

    for(int fr = 0; fr < maxfr; fr++) {
        for(int r = 0; r < T_ROWS; r++) {
            for(int x = 0; x < XGS; x++) {
                int ind = speed[r] > 0 ? TL(r)-1 + x - fr*speed[r]/2 : x - (XGS-1) - fr*speed[r]/2;
                g[x][r+1] = ind >= 0 && ind < TL(r) ? t[r][ind] : ' ';
            }
        }
        for(int x = Xmin; x <= Xmax; x++) {
            for(int y = Ymin; y <= Ymax; y++) {
                if(g[x][y] != ' ')
                    continue;
                for(unsigned m = 0; m < sizeof(mov)/sizeof(mov[0]); m++) {
                    int X = x + mov[m][0], Y = y + mov[m][1];
                    if(X < Xmin || X > Xmax || Y < Ymin || Y > Ymax)
                        continue;
                    if(!(mov[m][0]|mov[m][1]) && y > 0 && y > T_ROWS && g[x][y-speed[y-1]/4] != ' ')
                        continue;

                    int csor = ((X==Xmin|X==Xmax)&(Y==Ymin|Y==Ymax)&!bonusTwentyfive) << ((X==Xmax) + 2*(Y==Ymax));

                    for(int cs = 0; cs < NCST; cs++) {
                        int N = B(fr, cs, x, y);
                        if(!~N)
                            continue;
                        if((!(N&1) && y == 1 && Y == 0) ||
                              (N&1 && y == T_ROWS && Y == T_ROWS+1))
                            ++N;
                        if(N > B(fr+1, cs|csor, X, Y))
                            B(fr+1, cs|csor, X, Y) = N;
                    }


                }
            }
        }
    }

    int score = 0, xb, yb, cb, nb;
    for(int x = Xmin; x <= Xmax; x++) {
        for(int y = Ymin; y <= Ymax; y++) {
            for(int cs = 0; cs < NCST; cs++) {
                if(B(maxfr, cs, x, y) * (40 + bc(cs)) / 40 >= score) {
                    score = B(maxfr, cs, x, y) * (40 + bc(cs)) / 40;
                    xb = x, yb = y, cb = cs, nb = B(maxfr, cs, x, y);
                }
            }
        }
    }
    char *mvs = new char[maxfr+1];
    mvs[maxfr] = 0;

    for(int fr = maxfr-1; fr >= 0; --fr) {
        for(int r = 0; r < T_ROWS; r++) {
            for(int x = 0; x < XGS; x++) {
                int ind = speed[r] > 0 ? TL(r)-1 + x - fr*speed[r]/2 : x - (XGS-1) - fr*speed[r]/2;
                g[x][r+1] = ind >= 0 && ind < TL(r) ? t[r][ind] : ' ';
            }
        }
        for(int x = Xmin; x <= Xmax; x++) {
            for(int y = Ymin; y <= Ymax; y++) {
                if(g[x][y] != ' ')
                    continue;

                for(unsigned m = 0; m < sizeof(mov)/sizeof(mov[0]); m++) {
                    int X = x + mov[m][0], Y = y + mov[m][1];
                    if(X < Xmin || X > Xmax || Y < Ymin || Y > Ymax)
                        continue;
                    if(!(mov[m][0]|mov[m][1]) && y > 0 && y > T_ROWS && g[x][y-speed[y-1]/4] != ' ')
                        continue;

                    int csor = ((X==Xmin|X==Xmax)&(Y==Ymin|Y==Ymax)&!bonusTwentyfive) << ((X==Xmax) + 2*(Y==Ymax));

                    for(int cs = 0; cs < NCST; cs++) {
                        int N = B(fr, cs, x, y);
                        if(!~N)
                            continue;
                        if((!(N&1) && y == 1 && Y == 0) ||
                              (N&1 && y == T_ROWS && Y == T_ROWS+1))
                            ++N;
                        if(X==xb && Y==yb && N == nb && (cs|csor) == cb) {
                            mvs[fr] = mov[m][2];
                            xb = x, yb = y, nb = B(fr, cs, x, y), cb = cs;
                            goto fr_next;
                        }
                    }
                }
            }
        }
        errr(3623);
        fr_next:;
    }

    if((xb-Xstart)|(yb-Ymax)|nb)
        errr(789);
    #if DRAW

        for(int fr = 0; fr <= maxfr; ++fr) {
            memset(g, ' ', sizeof(g));
            for(int r = 0; r < T_ROWS; r++) {
                for(int x = 0; x < XGS; x++) {
                    int ind = speed[r] > 0 ? TL(r)-1 + x - fr*speed[r]/2 : x - (XGS-1) - fr*speed[r]/2;
                    ind >= 0 && ind < TL(r) ? g[x][r+1] = t[r][ind] : ' ';
                }
            }
            g[xb][yb] = 'F';
            for(int y = 0; y < YGS; y++) {
                for(int x = 0; x < XGS; x++)
                    cout<<g[x][y];
                cout<<endl;
            }
            cout<<string(XGS,'-')<<endl;
            usleep(55*1000);
            for(int i = 0; i < 5; i++) {
                if(mvs[fr] == mov[i][2]) {
                    xb += mov[i][0];
                    yb += mov[i][1];
                    break;
                }
            }
        }

    #endif
    cout<<score<<endl;
    cout<<mvs<<endl;
}

1
ฉันไม่แน่ใจว่าคุณนิยาม "รัฐ" ได้อย่างไร หากเราพิจารณาว่าสถานะระบบเป็นโปรไฟล์เวลาของการเคลื่อนไหวของกบมีประมาณ 5 ^ 3000 สถานะซึ่งสอดคล้องกับโปรไฟล์การเคลื่อนไหวสำหรับอินพุตที่เป็นไปได้ 5 ^ 3000 (อินพุตที่เป็นไปได้ห้ารายการต่อ ~ 3000 เฟรม) เห็นได้ชัดว่าเพียงเศษเสี้ยวของสิ่งเหล่านี้จะกลายเป็นสิ่งที่ยอมรับได้ แต่จำนวนของรัฐที่ยอมรับได้นั้นจะเป็นไปไม่ได้ที่จะค้นพบด้วยคำสั่งขนาดใหญ่หลายร้อยคำ เมื่อคุณส่งคำตอบสุดท้ายของคุณโปรดส่งรายการของการเคลื่อนไหวพร้อมกับมัน
COTO

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

@COTO ในการคำนวณ "สถานะ" ของฉันฉันลืมสิ่งสำคัญคือจำนวนของการข้ามดังนั้นฉันจึงพยายามให้คำอธิบายที่ชัดเจนยิ่งขึ้น สเป็คก็เขียนได้ค่อนข้างดี ดูเหมือนว่าฉันจะตีความปัญหาเหล่านี้ทั้งหมดอย่างถูกต้องในครั้งแรก
feersum

ฉันคำนวณค่าที่เหมาะสมเป็น 162 + 10% = 178 crossings แต่คุณอยู่ใกล้พอ ฉันไม่ต้องการให้เรื่องนี้กลายเป็นความโหดร้ายที่สามารถใช้ได้ แต่เห็นได้ชัดว่าฉันควรให้ปัญหามากกว่านี้ ในความเป็นธรรมฉันจะให้รางวัลคุณ 100 ตัวแทน
COTO

เห็นได้ชัดว่าฉันต้องรอ 24 ชั่วโมงก่อนที่จะได้รับ "เงินรางวัล" ด้วยเหตุผลอะไร: ใครจะรู้ SE ต้องไม่ต้องการคำตอบที่ให้รางวัลตรงเวลา หากเราทำเช่นนั้นผู้ก่อการร้ายจะชนะ : O
COTO
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.