トップページに戻る
次の競技プログラミングの問題へ
前の競技プログラミングの問題へ
ABC-054-B Template Matching
■■■問題■■■
縦N行、横N列に画素が並んだ画像Aと、縦M行、横M列に画素が並んだテンプレート画像Bが与えられます。
画素は画像を構成する最小単位であり、ここでは1×1の正方形とします。
また、与えられる画像は全て2値画像であり、各画素の色は白と黒の2種類で表されます。
入力において、全ての画素は文字で表されており、.は白色の画素、#は黒色の画素に対応します。
画像AはN個の文字列A1, ・・・ ,ANで表されます。
文字列Aiのj文字目は、画像Aの上からi番目、左からj番目の画素に対応します。(1 <= i,j <= N)
同様に、テンプレート画像BはM個の文字列B1, ・・・ ,BMで表されます。
文字列Biのj文字目は、テンプレート画像Bの上からi番目、左からj番目の画素に対応します。(1 <= i,j <= M)
画像の平行移動のみ許されるとき、テンプレート画像Bが画像Aの中に含まれているかを判定してください。
■■■入力■■■
N M
A1
A2
・
・
・
AN
B1
B2
・
・
・
BM
●1 <= M <= N <= 50
●Aiは#と.からなる長さNの文字列
●Biは#と.からなる長さMの文字列
■■■出力■■■
画像Aの中にテンプレート画像Bを含む場合はYes、含まない場合はNoを出力せよ。
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "Input1";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("3 2");
WillReturn.Add("#.#");
WillReturn.Add(".#.");
WillReturn.Add("#.#");
WillReturn.Add("#.");
WillReturn.Add(".#");
//Yes
//テンプレート画像Bが、
//画像A中の左上の2×2の部分画像と右下の2×2の部分画像に一致するため、
//Yesと出力します。
}
else if (InputPattern == "Input2") {
WillReturn.Add("4 1");
WillReturn.Add("....");
WillReturn.Add("....");
WillReturn.Add("....");
WillReturn.Add("....");
WillReturn.Add("#");
//No
//画像Aは白色の画素、
//テンプレート画像Bは黒色の画素で構成されるため、含まれることはありません。
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = InputList[0].Split(' ').Select(X => int.Parse(X)).ToArray();
int N = wkArr[0];
int M = wkArr[1];
var AList = new List<string>();
for (int I = 1; I <= N; I++) {
AList.Add(InputList[I]);
}
int UB_A = AList.Count - 1;
var BList = new List<string>();
for (int I = 1; I <= M; I++) {
BList.Add(InputList[N + I]);
}
int UB_B = BList.Count - 1;
for (int X1 = 0; X1 <= UB_A - UB_B; X1++) {
for (int Y1 = 0; Y1 <= UB_A - UB_B; Y1++) {
bool IsOK = true;
for (int X2 = 0; X2 <= UB_B; X2++) {
for (int Y2 = 0; Y2 <= UB_B; Y2++) {
if (AList[Y1 + Y2][X1 + X2] != BList[Y2][X2]) {
IsOK = false;
break;
}
}
if (IsOK == false) break;
}
if (IsOK) {
Console.WriteLine("Yes");
return;
}
}
}
Console.WriteLine("No");
}
}
解説
一致候補の始点座標を全探索してます。