「第17回オフラインリアルタイムどう書くの問題」をPHPで解く
http://nabetani.sakura.ne.jp/hena/ord17foldcut/
http://qiita.com/Nabetani/items/ebd9d7deb30c57447806
折って切る、何処かで見たと思ったら第18回の参考問題に似ている。
なので同じように考えれば解けるかな?
<?php
class FOLDCUT{
/**
* 折って切る
* @param String 「RRTRB-bl」みたいな文字列
* @return int 「6」みたいな数値
*/
public function get($input){
// 入力値を分解
$input = explode('-', $input);
$loop = str_split(strrev($input[0]), 1);
// 初期値を作成
switch($input[1]){
case 'tl': $data = ['01', '11']; break;
case 'tr': $data = ['10', '11']; break;
case 'bl': $data = ['11', '01']; break;
case 'br': $data = ['11', '10']; break;
}
// 展開する
foreach($loop as $key=>$val){
$data = $this->{'extract'.$val}($data);
}
// 穴を数えて返す
$count = $rowflg = $colflg = 0;
$collen = strlen($data[0]);
foreach($data as $row=>$line){
// 穴は必ず2*2になるので、右上でカウントしたら下の行は飛ばす
if($rowflg){ $rowflg=0;continue; }
$colflg = 0;
for($col=0;$col<$collen;$col++){
// 空があった
if(!$line[$col]){
// 最上段/最下段は穴にならない
if(!$row || !isset($data[$row+1])){
$rowflg++;
continue;
}
// 次が1であればカウント
if($colflg && isset($line[$col+1]) && $line[$col+1]){
$count++;
$rowflg++;
continue;
}
// 空がなかった
}else{
$colflg++;
}
}
}
return $count;
}
// 右半分を手前に折って、左半分に重ねる
private function extractR($data){
return array_map(function($val){
return $val . strrev($val);
}, $data);
}
// 左半分を手前に折って、右半分に重ねる
private function extractL($data){
return array_map(function($val){
return strrev($val) . $val;
}, $data);
}
// 上半分を手前に折って、下半分に重ねる
private function extractT($data){
return array_merge(array_reverse($data), $data);
}
// 下半分を手前に折って、上半分に重ねる
private function extractB($data){
return array_merge($data, array_reverse($data));
}
}
// 以下はテスト
$test = [
['RRTRB-bl', '6'],
['R-tr', '0'],
['L-br', '0'],
['T-tl', '0'],
['B-tl', '0'],
['BL-br', '0'],
['LB-tl', '0'],
['RL-tl', '0'],
['BL-tl', '0'],
['TL-bl', '0'],
['RT-tr', '1'],
['TRB-tl', '0'],
['TRL-bl', '0'],
['TRB-br', '2'],
['LLB-bl', '2'],
['RTL-tr', '1'],
['LBB-tr', '0'],
['TLL-tl', '2'],
['RLRR-tr', '0'],
['BBTL-tl', '4'],
['TBBT-tr', '0'],
['LLBR-tl', '0'],
['LBRT-tl', '2'],
['RLBL-bl', '4'],
['BRRL-br', '3'],
['TBBTL-tl', '8'],
['TLBBT-br', '0'],
['LRBLL-br', '7'],
['TRRTT-br', '6'],
['BBBLB-br', '0'],
['RTTTR-tl', '4'],
['BBLLL-br', '6'],
['RRLLTR-tr', '16'],
['TTRBLB-br', '8'],
['LRBRBR-bl', '14'],
['RBBLRL-tl', '8'],
['RTRLTB-tl', '12'],
['LBLRTR-tl', '14'],
['RRLTRL-tl', '16'],
['TBLTRR-br', '12'],
['TTTRLTT-bl', '30'],
['TBBRTBL-tr', '15'],
['TRTRTLL-tr', '28'],
['TLLRTRB-tr', '24'],
['RLLBRLB-tr', '15'],
['LTLRRBT-tr', '32'],
['RBBRBLT-br', '21'],
['LLRLRLR-tr', '0'],
];
$foldcut = new FOLDCUT();
foreach($test as $key=>$data){
$answer = $foldcut->get($data[0]);
if($answer !== (int)$data[1]){
print('えらー');
}
}
解けませんでした。
展開図を作るところまでは同じなので一瞬だったのですが、そこから穴の数をどうやって数えるのかというところで詰まった。
結局今回の展開図の特徴を用いた超力業で解きました。
かかった時間は1.5時間くらい。
絶対なんかもっとまともな数え方があるはず。
というか図にせずに計算する方法があるはず。
Author And Source
この問題について(「第17回オフラインリアルタイムどう書くの問題」をPHPで解く), 我々は、より多くの情報をここで見つけました https://qiita.com/rana_kualu/items/509f1cc9920ef1962ad4著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .