結果
| 問題 |
No.1916 Making Palindrome on Gird
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-04-29 23:58:09 |
| 言語 | C#(csc) (csc 3.9.0) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 4,306 bytes |
| コンパイル時間 | 3,435 ms |
| コンパイル使用メモリ | 109,184 KB |
| 実行使用メモリ | 46,464 KB |
| 最終ジャッジ日時 | 2024-06-29 05:49:16 |
| 合計ジャッジ時間 | 8,959 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 29 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 static System.Console;
using System.Linq;
using System.Collections.Generic;
class Program
{
static int NN => int.Parse(ReadLine());
static int[] NList => ReadLine().Split().Select(int.Parse).ToArray();
static string[] SList(int n) => Enumerable.Repeat(0, n).Select(_ => ReadLine()).ToArray();
static void Main()
{
var c = NList;
var (h, w) = (c[0], c[1]);
var map = SList(h);
if (map[0][0] != map[h - 1][w - 1])
{
WriteLine(0);
return;
}
var mod = 1_000_000_007;
var maxl = (h + w - 1) / 2;
var dp = new long[maxl][][];
dp[0] = new long[1][] { new [] { 1L } };
for (var i = 1; i < maxl; ++i)
{
var size = Math.Min(i + 1, Math.Min(h, w));
dp[i] = new long[size][];
for (var j = 0; j < dp[i].Length; ++j) dp[i][j] = new long[size];
for (var j = 0; j < size; ++j)
{
var dj = Pos(h, w, i, j);
for (var k = 0; k < size; ++k)
{
var dk = RevPos(h, w, i, k);
if (map[dj.h][dj.w] != map[dk.h][dk.w]) continue;
if (!Reachable(dj.h, dj.w, dk.h, dk.w)) continue;
var sub = 0L;
if (dj.h > 0 && dk.w + 1 < w && map[dj.h - 1][dj.w] == map[dk.h][dk.w + 1])
{
var pj = Lv(h, w, dj.h - 1, dj.w);
var pk = RevLv(h, w, dk.h, dk.w + 1);
sub += dp[i - 1][pj.i][pk.i];
}
if (dj.h > 0 && dk.h + 1 < h && map[dj.h - 1][dj.w] == map[dk.h + 1][dk.w])
{
var pj = Lv(h, w, dj.h - 1, dj.w);
var pk = RevLv(h, w, dk.h + 1, dk.w);
sub += dp[i - 1][pj.i][pk.i];
}
if (dj.w > 0 && dk.w + 1 < w && map[dj.h][dj.w - 1] == map[dk.h][dk.w + 1])
{
var pj = Lv(h, w, dj.h, dj.w - 1);
var pk = RevLv(h, w, dk.h, dk.w + 1);
sub += dp[i - 1][pj.i][pk.i];
}
if (dj.w > 0 && dk.h + 1 < h && map[dj.h][dj.w - 1] == map[dk.h + 1][dk.w])
{
var pj = Lv(h, w, dj.h, dj.w - 1);
var pk = RevLv(h, w, dk.h + 1, dk.w);
sub += dp[i - 1][pj.i][pk.i];
}
dp[i][j][k] = sub % mod;
}
}
}
var res = 0L;
if ((h + w) % 2 == 0)
{
var size = Math.Min(maxl, Math.Min(h, w));
for (var i = 0; i < size; ++i) for (var j = 0; j < size; ++j)
{
var pi = Pos(h, w, maxl - 1, i);
var pj = RevPos(h, w, maxl - 1, j);
if (!Reachable(pi.h, pi.w, pj.h, pj.w)) continue;
if (pi.w - pi.h == pj.w - pj.h) res += dp[maxl - 1][i][j] * 2;
else res += dp[maxl - 1][i][j];
}
}
else
{
var size = dp.Last().Length;
for (var i = 0; i < size; ++i) res += dp[maxl - 1][i][i];
if (h > w) for (var i = 0; i < size - 1; ++i) res += dp[maxl - 1][i + 1][i];
else for (var i = 0; i < size - 1; ++i) res += dp[maxl - 1][i][i + 1];
}
WriteLine(res % mod);
}
static (int h, int w) Pos(int h, int w, int lv, int i)
{
var rh = (lv >= w ? lv - w + 1 : 0) + i;
return (rh, lv - rh);
}
static (int h, int w) RevPos(int h, int w, int lv, int i)
{
var sum = h + w - 2 - lv;
var rh = Math.Max(0, sum - w + 1) + i;
return (rh, sum - rh);
}
static (int lv, int i) Lv(int h, int w, int rh, int rw)
{
var lv = rh + rw;
var toph = Math.Max(0, lv - w + 1);
return (lv, rh - toph);
}
static (int lv, int i) RevLv(int h, int w, int rh, int rw)
{
var lv = Lv(h, w, rh, rw);
return (h + w - 2 - lv.lv, lv.i);
}
static bool Reachable(int h1, int w1, int h2, int w2)
{
return h1 <= h2 && w1 <= w2;
}
}