結果

問題 No.367 ナイトの転身
ユーザー koba-e964koba-e964
提出日時 2016-05-20 18:00:30
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 415 ms / 2,000 ms
コード長 3,222 bytes
コンパイル時間 892 ms
コンパイル使用メモリ 98,788 KB
実行使用メモリ 48,976 KB
最終ジャッジ日時 2024-04-16 04:35:10
合計ジャッジ時間 3,294 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,812 KB
testcase_01 AC 2 ms
6,940 KB
testcase_02 AC 1 ms
6,944 KB
testcase_03 AC 1 ms
6,944 KB
testcase_04 AC 1 ms
6,944 KB
testcase_05 AC 1 ms
6,944 KB
testcase_06 AC 1 ms
6,940 KB
testcase_07 AC 1 ms
6,940 KB
testcase_08 AC 2 ms
6,944 KB
testcase_09 AC 2 ms
6,944 KB
testcase_10 AC 311 ms
48,776 KB
testcase_11 AC 415 ms
48,976 KB
testcase_12 AC 175 ms
20,912 KB
testcase_13 AC 160 ms
21,016 KB
testcase_14 AC 155 ms
20,080 KB
testcase_15 AC 5 ms
6,940 KB
testcase_16 AC 141 ms
18,136 KB
testcase_17 AC 16 ms
6,940 KB
testcase_18 AC 24 ms
6,944 KB
testcase_19 AC 43 ms
8,064 KB
testcase_20 AC 19 ms
6,944 KB
testcase_21 AC 44 ms
7,808 KB
testcase_22 AC 2 ms
6,940 KB
testcase_23 AC 3 ms
6,940 KB
testcase_24 AC 4 ms
6,944 KB
testcase_25 AC 3 ms
6,940 KB
testcase_26 AC 2 ms
6,944 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#define REP(i,s,n) for(int i=(int)(s);i<(int)(n);i++)

using namespace std;
typedef long long int ll;
typedef vector<int> VI;
typedef pair<int, int> PI;
const double EPS=1e-9;
const int inf = 0x1ffffff;

/**
 * Dijkstra's algorithm.
 * First, call add_edge() to add edges.
 * Second, call solve() to calculate the length of the shortest path from source to each vertex.
 * Header requirement: algorithm, queue, vector
 * Verified by AtCoder ARC026-C (http://arc026.contest.atcoder.jp/submissions/604231)
 */
 template<class Len = int>
class Dijkstra {
private:
  int n;
  std::vector<std::vector<std::pair<int, Len> > > edges;
public:
  /**
   * n: the number of vertices
   */
  Dijkstra(int n) : n(n), edges(n) {}
  /*
   * from: the source of edge to add
   * to: the target of edge to add
   * cost: the cost of edge to add
   */
  void add_edge(int from, int to, Len cost) {
    edges[from].push_back(std::pair<int, Len>(to, cost));
  }
  /*
   * This function returns an array consisting of the distances from vertex source.
   */
  std::vector<Len> solve(int source) {
    typedef std::pair<Len, int> pi;
    std::vector<Len> d(n, inf);
    std::priority_queue<pi, std::vector<pi>, std::greater<pi> > que;
    que.push(pi(0, source));
    while (!que.empty()) {
      pi p = que.top(); que.pop();
      int idx = p.second;
      if (d[idx] <= p.first) {
	continue;
      }
      d[idx] = p.first;
      for(int j = 0; j < edges[idx].size(); ++j) {
	que.push(pi(p.first + edges[idx][j].second, edges[idx][j].first));
      }
    }
    return d;
  }
};

string s[500];

int main(void){
  int h, w;
  cin >> h >> w;
  REP(i, 0, h) {
    cin >> s[i];
  }
  Dijkstra<int> dijk(2 * h * w);
  int knight[8][2]= {{-2, -1}, {-2, 1}, {-1, -2}, {-1, 2}, {1, -2}, {1,2}, {2,-1}, {2,1}};
  int bishop[4][2] = {{-1,-1}, {-1,1}, {1,-1}, {1,1}};
  REP(i, 0, h) {
    REP(j, 0, w) {
      REP(q, 0, 8) {
	int nx = i + knight[q][0];
	int ny = j + knight[q][1];
	if (0 > nx || nx >= h) continue;
	if (0 > ny || ny >= w) continue;
	int np = w * nx + ny;
	if (s[nx][ny] == 'R') {
	  np += w * h; // another world
	}
	dijk.add_edge(w * i + j, np, 1);
      }

      REP(q, 0, 4) {
	int nx = i + bishop[q][0];
	int ny = j + bishop[q][1];
	if (0 > nx || nx >= h) continue;
	if (0 > ny || ny >= w) continue;
	int np = w * nx + ny + w * h;
	if (s[nx][ny] == 'R') {
	  np -= w * h; // another world
	}
	dijk.add_edge(w * i + j + w * h, np, 1);
      }
    }
  }
  int sx = 0, sy = 0;
  int gx = 0, gy = 0;
  REP(i, 0, h) {
    REP(j, 0, w) {
      if (s[i][j] == 'S') {
	sx = i, sy = j;
      }
      if (s[i][j] == 'G') {
	gx = i, gy = j;
      }
    }
  }
  vector<int> result = dijk.solve(w * sx + sy);
  int g = w * gx + gy;
  int dist = min(result[g], result[g + w * h]);
  cout << (dist == inf ? -1 : dist) << endl;
}
0