Last active
December 12, 2015 04:51
-
-
Save nekko1119/3a08a6c1a99089e19646 to your computer and use it in GitHub Desktop.
パターンと完全一致する左上のピクセルの座標を半角スペース区切りで出力してください。パターンと完全一致する箇所は必ず1つだけ存在します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
入力 | |
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