結果

問題 No.1916 Making Palindrome on Gird
ユーザー tnakao0123tnakao0123
提出日時 2022-04-30 18:51:57
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 41 ms / 3,000 ms
コード長 2,761 bytes
コンパイル時間 574 ms
コンパイル使用メモリ 44,940 KB
実行使用メモリ 34,328 KB
最終ジャッジ日時 2023-09-12 11:17:23
合計ジャッジ時間 2,566 ms
ジャッジサーバーID
(参考情報)
judge12 / judge15
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 11 ms
34,288 KB
testcase_01 AC 11 ms
34,272 KB
testcase_02 AC 11 ms
34,284 KB
testcase_03 AC 10 ms
34,212 KB
testcase_04 AC 11 ms
34,224 KB
testcase_05 AC 11 ms
34,244 KB
testcase_06 AC 11 ms
34,204 KB
testcase_07 AC 11 ms
34,252 KB
testcase_08 AC 11 ms
34,216 KB
testcase_09 AC 10 ms
34,156 KB
testcase_10 AC 11 ms
34,244 KB
testcase_11 AC 11 ms
34,268 KB
testcase_12 AC 11 ms
34,232 KB
testcase_13 AC 13 ms
34,260 KB
testcase_14 AC 12 ms
34,176 KB
testcase_15 AC 19 ms
34,292 KB
testcase_16 AC 16 ms
34,180 KB
testcase_17 AC 24 ms
34,244 KB
testcase_18 AC 30 ms
34,300 KB
testcase_19 AC 29 ms
34,264 KB
testcase_20 AC 29 ms
34,244 KB
testcase_21 AC 29 ms
34,204 KB
testcase_22 AC 29 ms
34,324 KB
testcase_23 AC 17 ms
34,264 KB
testcase_24 AC 17 ms
34,320 KB
testcase_25 AC 16 ms
34,304 KB
testcase_26 AC 17 ms
34,256 KB
testcase_27 AC 17 ms
34,300 KB
testcase_28 AC 40 ms
34,328 KB
testcase_29 AC 41 ms
34,308 KB
testcase_30 AC 40 ms
34,264 KB
testcase_31 AC 40 ms
34,320 KB
testcase_32 AC 41 ms
34,248 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

/* -*- coding: utf-8 -*-
 *
 * 1916.cc:  No.1916 Making Palindrome on Gird - yukicoder
 */

#include<cstdio>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_H = 200;
const int MAX_W = 200;
const int MAX_D = (MAX_H + MAX_W) / 2;
const int MOD = 1000000007;

/* typedef */

template<const int MOD>
struct MI {
  int v;
  MI(): v() {}
  MI(int _v): v(_v % MOD) {}
  MI(long long _v): v(_v % MOD) {}

  MI operator+(const MI m) const { return MI(v + m.v); }
  MI operator-(const MI m) const { return MI(v + MOD - m.v); }
  MI operator*(const MI m) const { return MI((long long)v * m.v); }

  MI &operator+=(const MI m) { return (*this = *this + m); }
  MI &operator-=(const MI m) { return (*this = *this - m); }
  MI &operator*=(const MI m) { return (*this = *this * m); }
};

typedef MI<MOD> mi;

/* global variables */

char fs[MAX_H][MAX_W + 4];
mi dp[MAX_D][MAX_D][MAX_D];

/* subroutines */

inline void getst(int h, int w, int l, int &y, int &x) {
  x = min(l, w - 1), y = l - x;
}

inline bool inside(int y, int x, int h, int w) {
  return y >= 0 && y < h && x >= 0 && x < w;
}

/* main */

int main() {
  int h, w;
  scanf("%d%d", &h, &w);
  for (int i = 0; i < h; i++) scanf("%s", fs[i]);

  int l = h + w - 1;
  int l0, l1;
  if (l & 1) {
    l0 = l1 = l / 2;
    int y, x;
    getst(h, w, l0, y, x);
    for (int i = 0; inside(y, x, h, w); i++, y++, x--) dp[l0][i][i] = 1;
  }
  else {
    l0 = l / 2 - 1, l1 = l / 2;
    int y0, x0, y1, x1;
    getst(h, w, l0, y0, x0);
    getst(h, w, l1, y1, x1);
    for (int i = 0; inside(y0, x0, h, w); i++, y0++, x0--) {
      if (x0 + 1 < w && fs[y0][x0] == fs[y0][x0 + 1])
	dp[l0][i][x1 - (x0 + 1)] = 1;
      if (y0 + 1 < h && fs[y0][x0] == fs[y0 + 1][x0])
	dp[l0][i][x1 - x0] = 1;
    }
  }

  int gl0 = l0, gl1 = l1;
  for (; l0 > 0; l0--, l1++) {
    int sy0, sx0, sy1, sx1;
    getst(h, w, l0, sy0, sx0);
    getst(h, w, l1, sy1, sx1);
    int vy0, vx0, vy1, vx1;
    getst(h, w, l0 - 1, vy0, vx0);
    getst(h, w, l1 + 1, vy1, vx1);

    for (int i = 0, y0 = sy0, x0 = sx0;
	 inside(y0, x0, h, w); i++, y0++, x0--)
      for (int j = 0, y1 = sy1, x1 = sx1;
	   inside(y1, x1, h, w); j++, y1++, x1--)
	if (dp[l0][i][j].v != 0) {
	  if (x0 > 0 && x1 + 1 < w && fs[y0][x0 - 1] == fs[y1][x1 + 1])
	    dp[l0 - 1][vx0 - (x0 - 1)][vx1 - (x1 + 1)] += dp[l0][i][j];
	  if (x0 > 0 && y1 + 1 < h && fs[y0][x0 - 1] == fs[y1 + 1][x1])
	    dp[l0 - 1][vx0 - (x0 - 1)][vx1 - x1] += dp[l0][i][j];
	  if (y0 > 0 && x1 + 1 < w && fs[y0 - 1][x0] == fs[y1][x1 + 1])
	    dp[l0 - 1][vx0 - x0][vx1 - (x1 + 1)] += dp[l0][i][j];
	  if (y0 > 0 && y1 + 1 < h && fs[y0 - 1][x0] == fs[y1 + 1][x1])
	    dp[l0 - 1][vx0 - x0][vx1 - x1] += dp[l0][i][j];
	}
  }

  printf("%d\n", dp[0][0][0].v);

  return 0;
}
0