Skip to content

Instantly share code, notes, and snippets.

@nekko1119
Last active December 12, 2015 04:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nekko1119/3a08a6c1a99089e19646 to your computer and use it in GitHub Desktop.
Save nekko1119/3a08a6c1a99089e19646 to your computer and use it in GitHub Desktop.
パターンと完全一致する左上のピクセルの座標を半角スペース区切りで出力してください。パターンと完全一致する箇所は必ず1つだけ存在します。
/*
入力
4
0 0 1 0
0 1 1 0
0 1 0 1
1 1 1 0
3
0 1 1
0 1 0
1 1 1
出力
1 0
入力
4
0 0 0 0
0 0 1 1
0 0 1 1
0 0 0 0
2
1 1
1 1
出力
1 2
*/
#include <algorithm>
#include <iostream>
#include <iterator>
#include <limits>
#include <sstream>
#include <vector>
#include <string>
using graph_type = std::vector<std::vector<int>>;
std::vector<std::string> split(std::string const& input, char const delimiter)
{
std::istringstream iss{input};
std::string line;
std::vector<std::string> result;
while (std::getline(iss, line, delimiter)) {
result.emplace_back(line);
}
return result;
}
template <typename Stream>
void flush(Stream& stream) {
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
graph_type input()
{
int input_size;
std::cin >> input_size;
flush(std::cin);
std::vector<std::vector<int>> graph;
graph.reserve(input_size);
for (int i = 0; i < input_size; ++i) {
std::string line;
std::getline(std::cin, line);
auto const str_width = split(line, ' ');
if (str_width.size() != input_size) {
throw std::runtime_error{"wrong input"};
}
std::vector<int> width;
width.reserve(input_size);
std::transform(str_width.begin(), str_width.end(), std::back_inserter(width), [](std::string const& s) {
return std::stoi(s);
});
graph.emplace_back(std::move(width));
}
return graph;
}
using pos_type = std::pair<int, int>;
void increment_position(pos_type& pos, pos_type const& offset, int const width_return_pos = 0) noexcept
{
if (pos.first < offset.first - 1) {
++pos.first;
return;
}
if (pos.second < offset.second - 1) {
pos.first = width_return_pos;
++pos.second;
}
}
void increment_position(pos_type& pos, int const max_size, int const width_return_pos = 0) noexcept
{
increment_position(pos, std::make_pair(max_size, max_size), width_return_pos);
}
graph_type::value_type::const_reference at(graph_type const& graph, pos_type const& p)
{
return graph[p.second][p.first];
}
bool equal(pos_type const& current, graph_type const& graph, graph_type const& pattern)
{
auto pattern_pos = std::make_pair(0, 0);
auto current_pos = current;
auto const max_count = pattern.size() * pattern.size();
for (auto i = 0U; i < max_count; ++i) {
if (at(pattern, pattern_pos) != at(graph, current_pos)) {
return false;
}
increment_position(pattern_pos, pattern.size());
auto const offset = std::make_pair(current.first + pattern.size(), current.second + pattern.size());
increment_position(current_pos, offset, current.first);
}
return true;
}
int main()
{
auto const graph = input();
auto const pattern = input();
auto const shrink_size = graph.size() - pattern.size() + 1;
auto const trial_count = shrink_size * shrink_size;
auto pos = std::make_pair(0, 0);
for (auto i = 0U; i < trial_count; increment_position(pos, shrink_size), ++i) {
if (equal(pos, graph, pattern)) {
break;
}
}
std::cout << pos.second << " " << pos.first << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment