結果
| 問題 |
No.3 ビットすごろく
|
| コンテスト | |
| ユーザー |
velfare_nagata
|
| 提出日時 | 2016-10-05 14:04:03 |
| 言語 | C#(csc) (csc 3.9.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,690 bytes |
| コンパイル時間 | 881 ms |
| コンパイル使用メモリ | 114,716 KB |
| 実行使用メモリ | 30,652 KB |
| 最終ジャッジ日時 | 2024-11-21 17:17:56 |
| 合計ジャッジ時間 | 2,711 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 10 WA * 22 RE * 1 |
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (db94f4cc) Copyright (C) Microsoft Corporation. All rights reserved.
ソースコード
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;
}
}
}
velfare_nagata