結果

問題 No.3 ビットすごろく
ユーザー velfare_nagatavelfare_nagata
提出日時 2016-10-05 14:04:03
言語 C#(csc)
(csc 3.9.0)
結果
WA  
実行時間 -
コード長 3,690 bytes
コンパイル時間 2,733 ms
コンパイル使用メモリ 114,348 KB
実行使用メモリ 30,788 KB
最終ジャッジ日時 2024-05-01 12:49:28
合計ジャッジ時間 2,865 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 WA -
testcase_01 WA -
testcase_02 AC 23 ms
17,920 KB
testcase_03 AC 24 ms
18,688 KB
testcase_04 WA -
testcase_05 AC 25 ms
19,840 KB
testcase_06 AC 24 ms
18,688 KB
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 AC 24 ms
19,584 KB
testcase_13 AC 23 ms
18,688 KB
testcase_14 AC 26 ms
20,736 KB
testcase_15 AC 27 ms
21,120 KB
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 AC 27 ms
20,992 KB
testcase_23 AC 27 ms
21,504 KB
testcase_24 WA -
testcase_25 WA -
testcase_26 RE -
testcase_27 WA -
testcase_28 WA -
testcase_29 WA -
testcase_30 WA -
testcase_31 WA -
testcase_32 WA -
権限があれば一括ダウンロードができます
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (db94f4cc)
Copyright (C) Microsoft Corporation. All rights reserved.

ソースコード

diff #

using System;
using System.Collections;
using System.Diagnostics;

namespace CodeIq
{
	internal class Program
	{
		/// <summary>各数値に対応するビットフラグ数のテーブル</summary>
		private static Hashtable _bitCountTable;
		/// <summary>すごろくマス数</summary>
		private static int _n;
		/// <summary>計算要素スタック</summary>
		private static Stack _stack;
		/// <summary>位置に対応する最短手順数</summary>
		private static Hashtable _history;
		/// <summary>現時点での最短手</summary>
		private static int _nowBestOrderCount;

		/// <summary>
		/// Carol は特殊なすごろくをしようとしている。
		/// 
		/// 1からNの番号がふられている一直線に並べられているN個のマスがある。
		/// 1から開始のマスとして、ゴールはNが書かれているマスとする。
		/// 
		/// その場に書かれている数字の2進数で表現した時の1のビット数 だけ「前」または「後」に進めることができる。
		/// (1未満とN+1以上のマスには移動することは出来ない、正確にNにならないとゴールできない)
		/// 
		/// 自然数Nを与えられた時、ゴールに到達できる最短の移動数(開始のマスへも移動にカウントする)を求めてください。
		/// 到達できない場合は-1を出力してください。
		/// 
		/// 開始のマスがすでにゴールになっている場合もあリます。
		/// </summary>
		private static void Main()
		{
			var _n = int.Parse( Console.ReadLine() );
			//_n = 11;
			_nowBestOrderCount = int.MaxValue;
			_stack = new Stack();
			_history = new Hashtable();
			_stack.Push( 1 );
			_history.Add( 1, 1 );

			var getBitCount = new Func<int, int>( target =>
			{
				var bitCount = 0;
				for( ; target > 0; target &= target - 1 )
					bitCount++;
				return bitCount;
			} );

			_bitCountTable = new Hashtable();
			for( var i = 1; i < _n; i++ )
				_bitCountTable[i] = getBitCount( i );

			for( var i = 1; i <= _n; i++ )
				_history[i] = int.MaxValue;

			// ゴールまでの経路を計算する
			var result = Calculate( 1 );
			Debug.Print( ( result != int.MaxValue ? result : -1 ).ToString() );
			Console.WriteLine( ( result != int.MaxValue ? result : -1 ) );
		}

		private static int Calculate( int orderCount )
		{
			// 現時点での最短手を超過している場合はそれ以上計算しても無駄
			var pos = (int)_stack.Pop();
			if( orderCount > _nowBestOrderCount )
				return int.MaxValue;

			// 前方向と後方向への移動をそれぞれ計算する
			// ※前→後ろの順でチェックする
			if( pos == _n )
				return orderCount;

			// 移動先が範囲外だったり、前回来た時よりも手数を上回っている場合は処理しない
			// この時点で手数が上回っている場合はどうやっても巻き返せない
			var calcCount = 0;
			var backward = pos - (int)_bitCountTable[pos];
			if( ( backward > 0 && (int)_history[backward] > orderCount + 1 ) )
			{
				_stack.Push( backward );
				_history[backward] = orderCount + 1;
				calcCount ++;
			}
			var forward = pos + (int)_bitCountTable[pos];
			if( forward <= _n && ( (int)_history[forward] > orderCount + 1 ) )
			{
				_stack.Push( forward );
				_history[forward] = orderCount + 1;
				calcCount++;
			}

			var result = int.MaxValue;
			for( var i = 0; i < calcCount; i++ )
			{
				var calculatedCount = Calculate( orderCount + 1 );
				if( result > calculatedCount )
					result = calculatedCount;
				if( _nowBestOrderCount > result )
					_nowBestOrderCount = result;
			}
			return result;
		}
	}
}
0