#include <iostream>
#include <vector>
using namespace std;
struct Robot {
int x, y;
};
// Function to precompute distances to nearest obstacles
void precomputeDistances(vector<vector<char>>& matrix, vector<vector<int>>& left, vector<vector<int>>& top, vector<vector<int>>& right, vector<vector<int>>& bottom) {
int rows = matrix.size(), cols = matrix[0].size();
// Initialize DP arrays with 0 (as robots themselves are valid starting points)
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (matrix[i][j] == 'X') {
left[i][j] = top[i][j] = right[i][j] = bottom[i][j] = 0;
} else {
left[i][j] = top[i][j] = right[i][j] = bottom[i][j] = -1; // Mark uninitialized
}
}
}
// Pass 1: Compute left and top distances
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (matrix[i][j] == 'X') continue;
// Left Distance
if (j == 0 || matrix[i][j - 1] == 'X')
left[i][j] = 1;
else
left[i][j] = left[i][j - 1] + 1;
// Top Distance
if (i == 0 || matrix[i - 1][j] == 'X')
top[i][j] = 1;
else
top[i][j] = top[i - 1][j] + 1;
}
}
// Pass 2: Compute right and bottom distances
for (int i = rows - 1; i >= 0; i--) {
for (int j = cols - 1; j >= 0; j--) {
if (matrix[i][j] == 'X') continue;
// Right Distance
if (j == cols - 1 || matrix[i][j + 1] == 'X')
right[i][j] = 1;
else
right[i][j] = right[i][j + 1] + 1;
// Bottom Distance
if (i == rows - 1 || matrix[i + 1][j] == 'X')
bottom[i][j] = 1;
else
bottom[i][j] = bottom[i + 1][j] + 1;
}
}
}
// Function to check if a robot satisfies the query
bool isValidRobot(int i, int j, vector<int>& query, vector<vector<int>>& left, vector<vector<int>>& top, vector<vector<int>>& right, vector<vector<int>>& bottom) {
return left[i][j] == query[0] &&
top[i][j] == query[1] &&
right[i][j] == query[2] &&
bottom[i][j] == query[3];
}
// Function to find robots matching the query
vector<Robot> findRobots(vector<vector<char>>& matrix, vector<int>& query) {
int rows = matrix.size(), cols = matrix[0].size();
// DP arrays to store distances
vector<vector<int>> left(rows, vector<int>(cols, -1));
vector<vector<int>> top(rows, vector<int>(cols, -1));
vector<vector<int>> right(rows, vector<int>(cols, -1));
vector<vector<int>> bottom(rows, vector<int>(cols, -1));
// Precompute distances
precomputeDistances(matrix, left, top, right, bottom);
vector<Robot> robots;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (matrix[i][j] == 'O' && isValidRobot(i, j, query, left, top, right, bottom)) {
robots.push_back({i, j});
}
}
}
return robots;
}
int main() {
vector<vector<char>> matrix = {
{'O', 'E', 'E', 'E', 'E'},
{'E', 'O', 'X', 'E', 'E'},
{'X', 'E', 'X', 'X', 'E'},
{'E', 'E', 'O', 'X', 'E'},
{'X', 'E', 'X', 'E', 'E'}
};
vector<int> query = {2, 2, 4, 1};
vector<Robot> robots = findRobots(matrix, query);
cout << "Robots that match the query:\n";
for (auto& r : robots) {
cout << "Robot found at: (" << r.x << ", " << r.y << ")\n";
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnN0cnVjdCBSb2JvdCB7CiAgICBpbnQgeCwgeTsKfTsKCi8vIEZ1bmN0aW9uIHRvIHByZWNvbXB1dGUgZGlzdGFuY2VzIHRvIG5lYXJlc3Qgb2JzdGFjbGVzCnZvaWQgcHJlY29tcHV0ZURpc3RhbmNlcyh2ZWN0b3I8dmVjdG9yPGNoYXI+PiYgbWF0cml4LCB2ZWN0b3I8dmVjdG9yPGludD4+JiBsZWZ0LCB2ZWN0b3I8dmVjdG9yPGludD4+JiB0b3AsIHZlY3Rvcjx2ZWN0b3I8aW50Pj4mIHJpZ2h0LCB2ZWN0b3I8dmVjdG9yPGludD4+JiBib3R0b20pIHsKICAgIGludCByb3dzID0gbWF0cml4LnNpemUoKSwgY29scyA9IG1hdHJpeFswXS5zaXplKCk7CgogICAgLy8gSW5pdGlhbGl6ZSBEUCBhcnJheXMgd2l0aCAwIChhcyByb2JvdHMgdGhlbXNlbHZlcyBhcmUgdmFsaWQgc3RhcnRpbmcgcG9pbnRzKQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCByb3dzOyBpKyspIHsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGNvbHM7IGorKykgewogICAgICAgICAgICBpZiAobWF0cml4W2ldW2pdID09ICdYJykgewogICAgICAgICAgICAgICAgbGVmdFtpXVtqXSA9IHRvcFtpXVtqXSA9IHJpZ2h0W2ldW2pdID0gYm90dG9tW2ldW2pdID0gMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxlZnRbaV1bal0gPSB0b3BbaV1bal0gPSByaWdodFtpXVtqXSA9IGJvdHRvbVtpXVtqXSA9IC0xOyAgLy8gTWFyayB1bmluaXRpYWxpemVkCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gUGFzcyAxOiBDb21wdXRlIGxlZnQgYW5kIHRvcCBkaXN0YW5jZXMKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcm93czsgaSsrKSB7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBjb2xzOyBqKyspIHsKICAgICAgICAgICAgaWYgKG1hdHJpeFtpXVtqXSA9PSAnWCcpIGNvbnRpbnVlOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gTGVmdCBEaXN0YW5jZQogICAgICAgICAgICBpZiAoaiA9PSAwIHx8IG1hdHJpeFtpXVtqIC0gMV0gPT0gJ1gnKSAKICAgICAgICAgICAgICAgIGxlZnRbaV1bal0gPSAxOyAKICAgICAgICAgICAgZWxzZSAKICAgICAgICAgICAgICAgIGxlZnRbaV1bal0gPSBsZWZ0W2ldW2ogLSAxXSArIDE7CgogICAgICAgICAgICAvLyBUb3AgRGlzdGFuY2UKICAgICAgICAgICAgaWYgKGkgPT0gMCB8fCBtYXRyaXhbaSAtIDFdW2pdID09ICdYJykgCiAgICAgICAgICAgICAgICB0b3BbaV1bal0gPSAxOyAKICAgICAgICAgICAgZWxzZSAKICAgICAgICAgICAgICAgIHRvcFtpXVtqXSA9IHRvcFtpIC0gMV1bal0gKyAxOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBQYXNzIDI6IENvbXB1dGUgcmlnaHQgYW5kIGJvdHRvbSBkaXN0YW5jZXMKICAgIGZvciAoaW50IGkgPSByb3dzIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICBmb3IgKGludCBqID0gY29scyAtIDE7IGogPj0gMDsgai0tKSB7CiAgICAgICAgICAgIGlmIChtYXRyaXhbaV1bal0gPT0gJ1gnKSBjb250aW51ZTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFJpZ2h0IERpc3RhbmNlCiAgICAgICAgICAgIGlmIChqID09IGNvbHMgLSAxIHx8IG1hdHJpeFtpXVtqICsgMV0gPT0gJ1gnKSAKICAgICAgICAgICAgICAgIHJpZ2h0W2ldW2pdID0gMTsgCiAgICAgICAgICAgIGVsc2UgCiAgICAgICAgICAgICAgICByaWdodFtpXVtqXSA9IHJpZ2h0W2ldW2ogKyAxXSArIDE7CgogICAgICAgICAgICAvLyBCb3R0b20gRGlzdGFuY2UKICAgICAgICAgICAgaWYgKGkgPT0gcm93cyAtIDEgfHwgbWF0cml4W2kgKyAxXVtqXSA9PSAnWCcpIAogICAgICAgICAgICAgICAgYm90dG9tW2ldW2pdID0gMTsgCiAgICAgICAgICAgIGVsc2UgCiAgICAgICAgICAgICAgICBib3R0b21baV1bal0gPSBib3R0b21baSArIDFdW2pdICsgMTsKICAgICAgICB9CiAgICB9Cn0KCi8vIEZ1bmN0aW9uIHRvIGNoZWNrIGlmIGEgcm9ib3Qgc2F0aXNmaWVzIHRoZSBxdWVyeQpib29sIGlzVmFsaWRSb2JvdChpbnQgaSwgaW50IGosIHZlY3RvcjxpbnQ+JiBxdWVyeSwgdmVjdG9yPHZlY3RvcjxpbnQ+PiYgbGVmdCwgdmVjdG9yPHZlY3RvcjxpbnQ+PiYgdG9wLCB2ZWN0b3I8dmVjdG9yPGludD4+JiByaWdodCwgdmVjdG9yPHZlY3RvcjxpbnQ+PiYgYm90dG9tKSB7CiAgICByZXR1cm4gbGVmdFtpXVtqXSA9PSBxdWVyeVswXSAmJgogICAgICAgICAgIHRvcFtpXVtqXSA9PSBxdWVyeVsxXSAmJgogICAgICAgICAgIHJpZ2h0W2ldW2pdID09IHF1ZXJ5WzJdICYmCiAgICAgICAgICAgYm90dG9tW2ldW2pdID09IHF1ZXJ5WzNdOwp9CgovLyBGdW5jdGlvbiB0byBmaW5kIHJvYm90cyBtYXRjaGluZyB0aGUgcXVlcnkKdmVjdG9yPFJvYm90PiBmaW5kUm9ib3RzKHZlY3Rvcjx2ZWN0b3I8Y2hhcj4+JiBtYXRyaXgsIHZlY3RvcjxpbnQ+JiBxdWVyeSkgewogICAgaW50IHJvd3MgPSBtYXRyaXguc2l6ZSgpLCBjb2xzID0gbWF0cml4WzBdLnNpemUoKTsKICAgIAogICAgLy8gRFAgYXJyYXlzIHRvIHN0b3JlIGRpc3RhbmNlcwogICAgdmVjdG9yPHZlY3RvcjxpbnQ+PiBsZWZ0KHJvd3MsIHZlY3RvcjxpbnQ+KGNvbHMsIC0xKSk7CiAgICB2ZWN0b3I8dmVjdG9yPGludD4+IHRvcChyb3dzLCB2ZWN0b3I8aW50Pihjb2xzLCAtMSkpOwogICAgdmVjdG9yPHZlY3RvcjxpbnQ+PiByaWdodChyb3dzLCB2ZWN0b3I8aW50Pihjb2xzLCAtMSkpOwogICAgdmVjdG9yPHZlY3RvcjxpbnQ+PiBib3R0b20ocm93cywgdmVjdG9yPGludD4oY29scywgLTEpKTsKCiAgICAvLyBQcmVjb21wdXRlIGRpc3RhbmNlcwogICAgcHJlY29tcHV0ZURpc3RhbmNlcyhtYXRyaXgsIGxlZnQsIHRvcCwgcmlnaHQsIGJvdHRvbSk7CgogICAgdmVjdG9yPFJvYm90PiByb2JvdHM7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHJvd3M7IGkrKykgewogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgY29sczsgaisrKSB7CiAgICAgICAgICAgIGlmIChtYXRyaXhbaV1bal0gPT0gJ08nICYmIGlzVmFsaWRSb2JvdChpLCBqLCBxdWVyeSwgbGVmdCwgdG9wLCByaWdodCwgYm90dG9tKSkgewogICAgICAgICAgICAgICAgcm9ib3RzLnB1c2hfYmFjayh7aSwgan0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHJvYm90czsKfQoKaW50IG1haW4oKSB7CiAgICB2ZWN0b3I8dmVjdG9yPGNoYXI+PiBtYXRyaXggPSB7CiAgICAgICAgeydPJywgJ0UnLCAnRScsICdFJywgJ0UnfSwKICAgICAgICB7J0UnLCAnTycsICdYJywgJ0UnLCAnRSd9LAogICAgICAgIHsnWCcsICdFJywgJ1gnLCAnWCcsICdFJ30sCiAgICAgICAgeydFJywgJ0UnLCAnTycsICdYJywgJ0UnfSwKICAgICAgICB7J1gnLCAnRScsICdYJywgJ0UnLCAnRSd9CiAgICB9OwoKICAgIHZlY3RvcjxpbnQ+IHF1ZXJ5ID0gezIsIDIsIDQsIDF9OwogICAgdmVjdG9yPFJvYm90PiByb2JvdHMgPSBmaW5kUm9ib3RzKG1hdHJpeCwgcXVlcnkpOwoKICAgIGNvdXQgPDwgIlJvYm90cyB0aGF0IG1hdGNoIHRoZSBxdWVyeTpcbiI7CiAgICBmb3IgKGF1dG8mIHIgOiByb2JvdHMpIHsKICAgICAgICBjb3V0IDw8ICJSb2JvdCBmb3VuZCBhdDogKCIgPDwgci54IDw8ICIsICIgPDwgci55IDw8ICIpXG4iOwogICAgfQoKICAgIHJldHVybiAwOwp9Cg==