忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2024/05/09 03:06 |
PHP5.6.0 「第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時間くらい。

絶対なんかもっとまともな数え方があるはず。
というか図にせずに計算する方法があるはず。
PR


2014/04/07 23:05 | Comments(0) | PHP

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<PHP5.6の新機能 | HOME | 買ったものリスト 2014/04/06>>
忍者ブログ[PR]