提出 #65210376


ソースコード 拡げる

<?php
// ---------- 入力 ----------
function ints(){ $l = trim(fgets(STDIN)); return $l===''?[]:array_map('intval',explode(' ',$l)); }

[$N,$M] = ints();
$P=[];
for($i=0;$i<$M;$i++) $P[]=ints();

// 後で訪れることが確定しているマス
$willVisit=[];
foreach($P as $i=>$p)  $willVisit[$p[0]][$p[1]]=$i;

// ---------- パラメータ ----------
$maxWall   = 11;   // 置ける壁の上限
$beamWidth = 15;   // ビーム幅(大きくすると少し強いが計算量増)

// ---------- 移動/壁設置用ユーティリティ ----------
$DIR = [ [-1,0,'U'], [1,0,'D'], [0,-1,'L'], [0,1,'R'] ];

/* BFS (単移動+スライド) で最短手順を求め,行動列を返す   */
/* 到達不可のときは null を返す                                 */
function bfs(array &$map,int $N,int $sy,int $sx,int $gy,int $gx): ?array{
    if($sy==$gy && $sx==$gx) return [];
    $dist=array_fill(0,$N,array_fill(0,$N,99));
    $prev=array_fill(0,$N,array_fill(0,$N,null));
    $act =array_fill(0,$N,array_fill(0,$N,''));
    $q=new SplQueue();
    $dist[$sy][$sx]=0;
    $q->enqueue([$sy,$sx]);
    $DIR=[[-1,0,'U'],[1,0,'D'],[0,-1,'L'],[0,1,'R']];
    while(!$q->isEmpty()){
        [$y,$x]=$q->dequeue();
        if($y==$gy && $x==$gx){
            $res=[];
            while(!($y==$sy&&$x==$sx)){
                $res[]=$act[$y][$x];
                [$y,$x]=explode(',',$prev[$y][$x]);
                $y=(int)$y; $x=(int)$x;
            }
            return array_reverse($res);
        }
        // 単ステップ
        foreach($DIR as [$dy,$dx,$c]){
            $ny=$y+$dy; $nx=$x+$dx;
            if(($map[$ny][$nx]??1)===0 && $dist[$ny][$nx]>$dist[$y][$x]+1){
                $dist[$ny][$nx]=$dist[$y][$x]+1;
                $q->enqueue([$ny,$nx]);
                $prev[$ny][$nx]="$y,$x";
                $act [$ny][$nx]="M $c";
            }
        }
        // スライド
        foreach($DIR as [$dy,$dx,$c]){
            $ny=$y; $nx=$x;
            while(isset($map[$ny+$dy][$nx+$dx]) && $map[$ny+$dy][$nx+$dx]==0){
                $ny+=$dy; $nx+=$dx;
            }
            if(($ny!=$y||$nx!=$x) && $dist[$ny][$nx]>$dist[$y][$x]+1){
                $dist[$ny][$nx]=$dist[$y][$x]+1;
                $q->enqueue([$ny,$nx]);
                $prev[$ny][$nx]="$y,$x";
                $act [$ny][$nx]="S $c";
            }
        }
    }
    return null;
}

// ---------- ビームサーチ用状態 ----------
class State{
    public int $y,$x,$cost,$wallCnt;
    public array $map,$acts;
    function __construct($y,$x,$map,$cost,$wallCnt,$acts){
        $this->y=$y; $this->x=$x; $this->map=$map;
        $this->cost=$cost; $this->wallCnt=$wallCnt; $this->acts=$acts;
    }
}

// ---------- 初期状態 ----------
$emptyMap = array_fill(0,$N,array_fill(0,$N,0));
$states   = [ new State($P[0][0],$P[0][1],$emptyMap,0,0,[]) ];

// ---------- 区間ごとのビーム展開 ----------
for($step=1;$step<$M;$step++){
    $gy=$P[$step][0]; $gx=$P[$step][1];
    $next=[];
    foreach($states as $st){
        // ① 壁を置かない
        $variants = [ [$st->map, [], 0] ];
        // ② 壁を 1 枚置く(4 方向) -------------
        if($st->wallCnt < $maxWall){
            $dirs = $DIR;                // 乱択
            shuffle($dirs);
            foreach($dirs as [$dy,$dx,$c]){
                $wy = $st->y+$dy; $wx=$st->x+$dx;
                if($wy<0||$wy>=$N||$wx<0||$wx>=$N)          continue; // outside
                if($st->map[$wy][$wx]!=0)                   continue; // already wall
                if(isset($willVisit[$wy][$wx]) && $willVisit[$wy][$wx]>=$step) continue; // 未来の訪問予定
                $newMap = $st->map;
                $newMap[$wy][$wx]=1;
                $variants[] = [ $newMap, ["A $c"], 1 ];
            }
        }
        // ---- 各バリアントを評価 ----
        foreach($variants as [$candMap,$addActs,$addWall]){
            $path = bfs($candMap,$N,$st->y,$st->x,$gy,$gx);
            if($path===null) continue;                      // 到達不可
            $acts = array_merge($st->acts,$addActs,$path);
            $cost = $st->cost + $addWall + count($path);
            $next[] = new State($gy,$gx,$candMap,$cost,$st->wallCnt+$addWall,$acts);
        }
    }
    if(!$next){  // 何らかの理由で空になったら壁を置かずに強制遷移
        foreach($states as $st){
            $path=bfs($st->map,$N,$st->y,$st->x,$gy,$gx);
            if($path===null) continue;
            $next[] = new State($gy,$gx,$st->map,
                                 $st->cost+count($path),
                                 $st->wallCnt,
                                 array_merge($st->acts,$path));
        }
    }
    // コスト昇順でビーム幅分に絞る
    usort($next, fn($a,$b)=>$a->cost<=>$b->cost);
    $states = array_slice($next,0,$beamWidth);
}

// ---------- 出力 ----------
$best=$states[0];
foreach($best->acts as $line) echo $line,"\n";
?>

提出情報

提出日時
問題 A - Skating with Blocks
ユーザ yoichiro
言語 PHP (php 8.2.8)
得点 213213
コード長 5117 Byte
結果 AC
実行時間 1343 ms
メモリ 23516 KiB

ジャッジ結果

セット名 test_ALL
得点 / 配点 213213 / 246000
結果
AC × 150
セット名 テストケース
test_ALL test_0000.txt, test_0001.txt, test_0002.txt, test_0003.txt, test_0004.txt, test_0005.txt, test_0006.txt, test_0007.txt, test_0008.txt, test_0009.txt, test_0010.txt, test_0011.txt, test_0012.txt, test_0013.txt, test_0014.txt, test_0015.txt, test_0016.txt, test_0017.txt, test_0018.txt, test_0019.txt, test_0020.txt, test_0021.txt, test_0022.txt, test_0023.txt, test_0024.txt, test_0025.txt, test_0026.txt, test_0027.txt, test_0028.txt, test_0029.txt, test_0030.txt, test_0031.txt, test_0032.txt, test_0033.txt, test_0034.txt, test_0035.txt, test_0036.txt, test_0037.txt, test_0038.txt, test_0039.txt, test_0040.txt, test_0041.txt, test_0042.txt, test_0043.txt, test_0044.txt, test_0045.txt, test_0046.txt, test_0047.txt, test_0048.txt, test_0049.txt, test_0050.txt, test_0051.txt, test_0052.txt, test_0053.txt, test_0054.txt, test_0055.txt, test_0056.txt, test_0057.txt, test_0058.txt, test_0059.txt, test_0060.txt, test_0061.txt, test_0062.txt, test_0063.txt, test_0064.txt, test_0065.txt, test_0066.txt, test_0067.txt, test_0068.txt, test_0069.txt, test_0070.txt, test_0071.txt, test_0072.txt, test_0073.txt, test_0074.txt, test_0075.txt, test_0076.txt, test_0077.txt, test_0078.txt, test_0079.txt, test_0080.txt, test_0081.txt, test_0082.txt, test_0083.txt, test_0084.txt, test_0085.txt, test_0086.txt, test_0087.txt, test_0088.txt, test_0089.txt, test_0090.txt, test_0091.txt, test_0092.txt, test_0093.txt, test_0094.txt, test_0095.txt, test_0096.txt, test_0097.txt, test_0098.txt, test_0099.txt, test_0100.txt, test_0101.txt, test_0102.txt, test_0103.txt, test_0104.txt, test_0105.txt, test_0106.txt, test_0107.txt, test_0108.txt, test_0109.txt, test_0110.txt, test_0111.txt, test_0112.txt, test_0113.txt, test_0114.txt, test_0115.txt, test_0116.txt, test_0117.txt, test_0118.txt, test_0119.txt, test_0120.txt, test_0121.txt, test_0122.txt, test_0123.txt, test_0124.txt, test_0125.txt, test_0126.txt, test_0127.txt, test_0128.txt, test_0129.txt, test_0130.txt, test_0131.txt, test_0132.txt, test_0133.txt, test_0134.txt, test_0135.txt, test_0136.txt, test_0137.txt, test_0138.txt, test_0139.txt, test_0140.txt, test_0141.txt, test_0142.txt, test_0143.txt, test_0144.txt, test_0145.txt, test_0146.txt, test_0147.txt, test_0148.txt, test_0149.txt
ケース名 結果 実行時間 メモリ
test_0000.txt AC 1343 ms 22388 KiB
test_0001.txt AC 610 ms 23132 KiB
test_0002.txt AC 576 ms 23100 KiB
test_0003.txt AC 609 ms 22884 KiB
test_0004.txt AC 523 ms 22848 KiB
test_0005.txt AC 511 ms 23192 KiB
test_0006.txt AC 574 ms 22788 KiB
test_0007.txt AC 614 ms 22996 KiB
test_0008.txt AC 588 ms 23204 KiB
test_0009.txt AC 584 ms 22804 KiB
test_0010.txt AC 666 ms 22876 KiB
test_0011.txt AC 583 ms 23064 KiB
test_0012.txt AC 542 ms 23448 KiB
test_0013.txt AC 492 ms 23096 KiB
test_0014.txt AC 557 ms 23220 KiB
test_0015.txt AC 460 ms 23288 KiB
test_0016.txt AC 595 ms 23004 KiB
test_0017.txt AC 555 ms 23192 KiB
test_0018.txt AC 582 ms 23212 KiB
test_0019.txt AC 632 ms 23136 KiB
test_0020.txt AC 573 ms 23216 KiB
test_0021.txt AC 667 ms 22988 KiB
test_0022.txt AC 678 ms 22960 KiB
test_0023.txt AC 651 ms 23100 KiB
test_0024.txt AC 521 ms 23044 KiB
test_0025.txt AC 540 ms 23208 KiB
test_0026.txt AC 604 ms 22772 KiB
test_0027.txt AC 615 ms 23004 KiB
test_0028.txt AC 529 ms 22952 KiB
test_0029.txt AC 663 ms 22956 KiB
test_0030.txt AC 526 ms 22832 KiB
test_0031.txt AC 598 ms 22860 KiB
test_0032.txt AC 607 ms 23200 KiB
test_0033.txt AC 529 ms 23068 KiB
test_0034.txt AC 599 ms 23096 KiB
test_0035.txt AC 573 ms 23028 KiB
test_0036.txt AC 543 ms 22920 KiB
test_0037.txt AC 625 ms 23020 KiB
test_0038.txt AC 693 ms 23080 KiB
test_0039.txt AC 690 ms 23036 KiB
test_0040.txt AC 599 ms 23204 KiB
test_0041.txt AC 578 ms 23172 KiB
test_0042.txt AC 537 ms 23132 KiB
test_0043.txt AC 517 ms 23264 KiB
test_0044.txt AC 584 ms 23156 KiB
test_0045.txt AC 528 ms 23032 KiB
test_0046.txt AC 645 ms 23316 KiB
test_0047.txt AC 572 ms 23000 KiB
test_0048.txt AC 628 ms 22992 KiB
test_0049.txt AC 530 ms 23024 KiB
test_0050.txt AC 559 ms 23272 KiB
test_0051.txt AC 568 ms 23172 KiB
test_0052.txt AC 670 ms 22792 KiB
test_0053.txt AC 499 ms 23128 KiB
test_0054.txt AC 604 ms 23188 KiB
test_0055.txt AC 560 ms 22904 KiB
test_0056.txt AC 606 ms 23288 KiB
test_0057.txt AC 516 ms 22932 KiB
test_0058.txt AC 594 ms 23188 KiB
test_0059.txt AC 668 ms 23204 KiB
test_0060.txt AC 573 ms 22992 KiB
test_0061.txt AC 550 ms 23068 KiB
test_0062.txt AC 524 ms 23068 KiB
test_0063.txt AC 541 ms 23268 KiB
test_0064.txt AC 562 ms 23196 KiB
test_0065.txt AC 567 ms 22740 KiB
test_0066.txt AC 593 ms 22976 KiB
test_0067.txt AC 629 ms 23068 KiB
test_0068.txt AC 552 ms 23100 KiB
test_0069.txt AC 528 ms 23056 KiB
test_0070.txt AC 646 ms 23320 KiB
test_0071.txt AC 618 ms 22932 KiB
test_0072.txt AC 553 ms 22972 KiB
test_0073.txt AC 566 ms 23140 KiB
test_0074.txt AC 583 ms 23040 KiB
test_0075.txt AC 573 ms 23168 KiB
test_0076.txt AC 488 ms 23392 KiB
test_0077.txt AC 586 ms 23516 KiB
test_0078.txt AC 600 ms 22916 KiB
test_0079.txt AC 540 ms 23244 KiB
test_0080.txt AC 620 ms 23060 KiB
test_0081.txt AC 523 ms 22992 KiB
test_0082.txt AC 514 ms 23144 KiB
test_0083.txt AC 571 ms 22760 KiB
test_0084.txt AC 500 ms 23060 KiB
test_0085.txt AC 604 ms 23056 KiB
test_0086.txt AC 527 ms 22888 KiB
test_0087.txt AC 616 ms 23340 KiB
test_0088.txt AC 560 ms 22760 KiB
test_0089.txt AC 602 ms 23208 KiB
test_0090.txt AC 634 ms 22844 KiB
test_0091.txt AC 564 ms 23472 KiB
test_0092.txt AC 638 ms 22796 KiB
test_0093.txt AC 679 ms 23132 KiB
test_0094.txt AC 528 ms 23268 KiB
test_0095.txt AC 529 ms 23028 KiB
test_0096.txt AC 600 ms 23208 KiB
test_0097.txt AC 523 ms 22876 KiB
test_0098.txt AC 642 ms 22896 KiB
test_0099.txt AC 562 ms 23188 KiB
test_0100.txt AC 510 ms 22956 KiB
test_0101.txt AC 494 ms 23316 KiB
test_0102.txt AC 639 ms 23060 KiB
test_0103.txt AC 558 ms 23208 KiB
test_0104.txt AC 664 ms 23068 KiB
test_0105.txt AC 537 ms 23144 KiB
test_0106.txt AC 611 ms 23060 KiB
test_0107.txt AC 549 ms 23136 KiB
test_0108.txt AC 633 ms 23012 KiB
test_0109.txt AC 569 ms 23076 KiB
test_0110.txt AC 592 ms 23136 KiB
test_0111.txt AC 602 ms 22944 KiB
test_0112.txt AC 541 ms 22924 KiB
test_0113.txt AC 680 ms 23144 KiB
test_0114.txt AC 549 ms 23268 KiB
test_0115.txt AC 621 ms 23068 KiB
test_0116.txt AC 579 ms 23228 KiB
test_0117.txt AC 580 ms 22984 KiB
test_0118.txt AC 738 ms 23040 KiB
test_0119.txt AC 603 ms 23296 KiB
test_0120.txt AC 552 ms 22864 KiB
test_0121.txt AC 557 ms 22988 KiB
test_0122.txt AC 519 ms 23232 KiB
test_0123.txt AC 596 ms 23320 KiB
test_0124.txt AC 554 ms 22984 KiB
test_0125.txt AC 486 ms 23248 KiB
test_0126.txt AC 552 ms 23120 KiB
test_0127.txt AC 546 ms 23212 KiB
test_0128.txt AC 603 ms 23188 KiB
test_0129.txt AC 514 ms 23264 KiB
test_0130.txt AC 637 ms 23108 KiB
test_0131.txt AC 535 ms 23044 KiB
test_0132.txt AC 456 ms 23052 KiB
test_0133.txt AC 678 ms 23188 KiB
test_0134.txt AC 551 ms 23172 KiB
test_0135.txt AC 562 ms 22896 KiB
test_0136.txt AC 570 ms 23216 KiB
test_0137.txt AC 620 ms 23008 KiB
test_0138.txt AC 515 ms 22912 KiB
test_0139.txt AC 665 ms 23148 KiB
test_0140.txt AC 622 ms 23116 KiB
test_0141.txt AC 614 ms 23172 KiB
test_0142.txt AC 541 ms 23008 KiB
test_0143.txt AC 534 ms 22972 KiB
test_0144.txt AC 709 ms 22988 KiB
test_0145.txt AC 583 ms 23144 KiB
test_0146.txt AC 603 ms 22936 KiB
test_0147.txt AC 579 ms 22776 KiB
test_0148.txt AC 642 ms 23128 KiB
test_0149.txt AC 586 ms 22884 KiB