Submission details
Task:Hypyt
Sender:rottis
Submission time:2025-10-28 02:02:36 +0200
Language:C++ (C++17)
Status:READY
Result:30
Feedback
groupverdictscore
#1ACCEPTED10
#2ACCEPTED20
#30
#40
#50
Test results
testverdicttimegroup
#1ACCEPTED0.00 s1, 2, 3, 4, 5details
#2ACCEPTED0.00 s1, 2, 3, 4, 5details
#3ACCEPTED0.00 s1, 2, 3, 4, 5details
#4ACCEPTED0.00 s1, 2, 3, 4, 5details
#5ACCEPTED0.00 s1, 2, 3, 4, 5details
#6ACCEPTED0.20 s2, 5details
#7ACCEPTED0.25 s2, 5details
#8ACCEPTED0.20 s2, 5details
#9--3, 4, 5details
#10--3, 4, 5details
#11--3, 4, 5details
#12--4, 5details
#13--4, 5details
#14--4, 5details
#15--5details
#16--5details
#17--5details
#18--5details
#19--5details
#20--5details
#21--5details
#22ACCEPTED0.00 s1, 2, 3, 4, 5details
#23ACCEPTED0.00 s1, 2, 3, 4, 5details
#24--5details
#25--5details
#26--5details
#27ACCEPTED0.52 s5details

Compiler report

input/code.cpp: In function 'int main()':
input/code.cpp:199:23: warning: comparison of integer expressions of different signedness: 'int' and 'uint' {aka 'unsigned int'} [-Wsign-compare]
  199 |     for (int y = 0; y < hgt; y++) {
      |                     ~~^~~~~
input/code.cpp:201:27: warning: comparison of integer expressions of different signedness: 'int' and 'uint' {aka 'unsigned int'} [-Wsign-compare]
  201 |         for (int x = 0; x < wid; x++) {
      |                         ~~^~~~~

Code

// TODO:
// optimize!
// store some results of previous calculations somehow
// board is only 250x250, so caching a lot is fine

#include <iostream>
#include <string>
#include <unordered_set>
#include <map>
#include <queue>

#define is_movable(char) (char == '.')
#define Queue std::priority_queue<AStarNode, std::vector<AStarNode>, Compare>


typedef unsigned int uint;

typedef struct vec2 {
    int x;
    int y;
} vec2;

inline long long to_long(vec2 pos) {
    long long retval;
    retval = pos.x;
    retval <<= 32;
    retval |= pos.y;
    return retval;
}

class GraphEdge;

class GraphNode {
public:
    int network_number = -1; // if multiple disconnected graphs, save performance with this
    vec2 pos;
    std::vector<GraphEdge> warps;
    
    GraphNode(vec2 pos_) {
        pos = pos_;
    }

    GraphNode() {}
};

class GraphEdge {
public:
    int cost;
    GraphNode *destination;

    GraphEdge(GraphNode *destination_, int cost_) {
        cost = cost_;
        destination = destination_;
    }
};

const uint BSIZE = 250;

std::vector<GraphNode> rows[BSIZE];
std::vector<GraphNode> columns[BSIZE];
std::map<long long, GraphNode> nodes;

inline GraphNode get_node(vec2 pos) {
    return nodes[to_long(pos)];
}

void connect_nodes(vec2 pos1, vec2 pos2, int cost) {
    GraphNode first = nodes[to_long(pos1)];
    GraphNode second = nodes[to_long(pos2)];

    first.warps.push_back(
        GraphEdge(&second, cost)
    );

    second.warps.push_back(
        GraphEdge(&first, cost)
    );
}

class AStarNode {
public:
    int cost;
    int heuristic;
    vec2 pos;

    AStarNode(int cost_, int heuristic_, vec2 pos_) {
        cost = cost_;
        heuristic = heuristic_;
        pos = pos_;
    }
};

class Compare
{
public:
    bool operator() (AStarNode a, AStarNode b)
    {
        return a.cost + a.heuristic > b.cost + b.heuristic;
    }
};

inline vec2 vec2_add(vec2 a, vec2 b) {
    return vec2 { a.x + b.x, a.y + b.y};
}

inline bool vec2_neq(vec2 a, vec2 b) {
    return (a.x != b.x || a.y != b.y); 
}

inline bool vec2_eq(vec2 a, vec2 b) {
    return (a.x == b.x && a.y == b.y);
}

uint hgt, wid;


int heuristic(vec2 pos, vec2 end) {
    if (vec2_eq(pos, end)) { return 0; }
    if (pos.x == end.x || pos.y == end.y) {
        return 1;
    }
    return 2;
}

int algorithm(vec2 start, vec2 end) {
    GraphNode start_node = get_node(start);
    GraphNode end_node = get_node(end);

    if (start_node.network_number != -1 && end_node.network_number != -1 && start_node.network_number != end_node.network_number) {
        return -1;
    }

    Queue queue;
    std::unordered_set<long long> already_visited;

    already_visited.insert(to_long(start));

    queue.push(AStarNode(0, heuristic(start, end), start));
    //std::cout << "s: " << start.x << ' ' << start.y << ", e: " << end.x << ' ' << end.y << ", heuristic: " << heuristic(start, end) << std::endl;
    while (!queue.empty()) {
        AStarNode cur = queue.top();
        queue.pop();
        //std::cout << "cpos: (" << cur.pos.x << ", " << cur.pos.y << "), cost: " << cur.cost << ", heuristic: " << cur.heuristic << std::endl;
        
        if (start_node.network_number != -1) {
            GraphNode cur_node = get_node(cur.pos);
            cur_node.network_number = start_node.network_number;
        }

        //connect_nodes(start, cur.pos, cur.cost);
        
        if (vec2_eq(cur.pos, end)) {
            return cur.cost;
        }

        for (GraphNode node : columns[cur.pos.x]) {
            //std::cout << "cx: " << x << std::endl;
            vec2 pos = node.pos;
            
            //std::cout << (!board[pos.y][pos.x]) << (cur.pos.x == x) << (already_visited.count(to_long(pos)) > 0) << std::endl;
            if (already_visited.count(to_long(pos)) > 0) { continue; }

            already_visited.insert(to_long(pos));
            queue.push(AStarNode(cur.cost + 1, heuristic(pos, end), pos));
        }

        for (GraphNode node : rows[cur.pos.y]) {
            //std::cout << "cy: " << y << std::endl;
            vec2 pos = node.pos;
            
            //std::cout << (!board[pos.y][pos.x]) << (cur.pos.y == y) << (already_visited.count(to_long(pos)) > 0) << std::endl;
            if (already_visited.count(to_long(pos)) > 0) { continue; }

            already_visited.insert(to_long(pos));
            queue.push(AStarNode(cur.cost + 1, heuristic(pos, end), pos));
        }

        for (GraphEdge edge : nodes[to_long(cur.pos)].warps) {
            GraphNode *node = edge.destination;
            vec2 pos = node->pos;

            if (already_visited.count(to_long(pos)) > 0) { continue; }

            already_visited.insert(to_long(pos));
            queue.push(AStarNode(cur.cost + edge.cost, heuristic(node->pos, end), pos));

        }
    }

    return -1;
}

int main() {
    uint q;

    std::cin >> hgt >> wid >> q;

    char buf[BSIZE+1];
    for (int y = 0; y < hgt; y++) {
        std::cin >> buf;
        for (int x = 0; x < wid; x++) {
            if (is_movable(buf[x])) {
                GraphNode node = GraphNode({ x, y });

                columns[x].push_back(node);
                rows[y].push_back(node);
                nodes[to_long({x, y})] = node;
            }
        }
    }

    for (uint i = 0; i < q; i++) {
        int startx, starty, endx, endy;
        std::cin >> starty >> startx >> endy >> endx;
        
        vec2 start = { startx - 1, starty - 1 };
        vec2 end = { endx - 1, endy - 1 };
        
        std::cout << algorithm(start, end) << std::endl;
    }

    return 0;
}

Test details

Test 1 (public)

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
4 6 5
.*.***
*...**
*****.
*..*.*
...

correct output
1
0
3
3
-1

user output
1
0
3
3
-1

Test 2

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
10 10 10
..........
.....*....
........*.
*.*....*..
...

correct output
1
2
1
2
2
...

user output
1
2
1
2
2
...

Test 3

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
10 10 10
*...***.**
*****.*...
**..**.**.
..**.**.*.
...

correct output
1
2
2
1
2
...

user output
1
2
2
1
2
...

Test 4

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
10 10 10
***.*.****
**********
*.********
.*.***.**.
...

correct output
3
4
2
3
4
...

user output
3
4
2
3
4
...

Test 5

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
10 10 1
.****.****
**.**..***
**********
*******..*
...

correct output
7

user output
7

Test 6

Group: 2, 5

Verdict: ACCEPTED

input
250 250 250
.*...*.....*******..**...*.......

correct output
2
3
3
2
2
...

user output
2
3
3
2
2
...

Test 7

Group: 2, 5

Verdict: ACCEPTED

input
250 250 250
...*......**.**.*.*..**..*..**...

correct output
2
2
2
2
3
...

user output
2
2
2
2
3
...

Test 8

Group: 2, 5

Verdict: ACCEPTED

input
250 250 250
**..**..****.****.*.***.***..*...

correct output
2
3
3
3
3
...

user output
2
3
3
3
3
...

Test 9

Group: 3, 4, 5

Verdict:

input
40 40 200000
...*.**.*..*.............*.*.....

correct output
2
2
2
2
2
...

user output
(empty)

Test 10

Group: 3, 4, 5

Verdict:

input
40 40 200000
**.**..*.*.*.******....****.*....

correct output
2
1
3
2
2
...

user output
(empty)

Test 11

Group: 3, 4, 5

Verdict:

input
40 40 200000
.*.*.**.*****.***.*.****.**.**...

correct output
3
3
3
3
3
...

user output
(empty)

Test 12

Group: 4, 5

Verdict:

input
80 80 200000
*....**.***..****...*.....*......

correct output
2
2
2
2
2
...

user output
(empty)

Test 13

Group: 4, 5

Verdict:

input
80 80 200000
.***.*..*.***..*****....**...*...

correct output
3
2
2
3
2
...

user output
(empty)

Test 14

Group: 4, 5

Verdict:

input
80 80 200000
*******.*****.*..*..****...***...

correct output
2
3
1
2
2
...

user output
(empty)

Test 15

Group: 5

Verdict:

input
250 250 200000
*....*..*..*..**..*.........**...

correct output
3
2
2
2
2
...

user output
(empty)

Test 16

Group: 5

Verdict:

input
250 250 200000
..*....*..*......*.**.*.*..***...

correct output
2
2
2
2
2
...

user output
(empty)

Test 17

Group: 5

Verdict:

input
250 250 200000
*..*.*****.*********.****.****...

correct output
3
3
2
2
2
...

user output
(empty)

Test 18

Group: 5

Verdict:

input
250 250 200000
*********.**********.******.**...

correct output
3
3
3
3
3
...

user output
(empty)

Test 19

Group: 5

Verdict:

input
250 250 200000
.*****************************...

correct output
104
422
145
93
65
...

user output
(empty)

Test 20

Group: 5

Verdict:

input
250 250 200000
..****************************...

correct output
57
155
38
65
98
...

user output
(empty)

Test 21

Group: 5

Verdict:

input
250 250 200000
.*****************************...

correct output
498
498
498
498
498
...

user output
(empty)

Test 22

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
10 1 10
*
*
.
*
...

correct output
0
1
1
0
0
...

user output
0
1
1
0
0
...

Test 23

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
1 10 10
........*.
1 7 1 10
1 4 1 7
1 5 1 1
...

correct output
1
1
1
1
1
...

user output
1
1
1
1
1
...

Test 24

Group: 5

Verdict:

input
250 1 200000
*
.
*
.
...

correct output
1
1
1
1
1
...

user output
(empty)

Test 25

Group: 5

Verdict:

input
1 250 200000
*.*.*...*.*.**.***..**.*.*..**...

correct output
1
1
1
1
1
...

user output
(empty)

Test 26

Group: 5

Verdict:

input
250 250 200000
.................................

correct output
2
2
2
2
2
...

user output
(empty)

Test 27

Group: 5

Verdict: ACCEPTED

input
250 250 200000
******************************...

correct output
0
0
0
0
0
...

user output
0
0
0
0
0
...