6 条题解

  • 1
    @ 2026-03-14 00:27:11
    #include <iostream>
    #include <vector>
    #include <queue>
    #include <map>
    #include <tuple>
    #include <algorithm>
    using namespace std;
    
    int dist[5][5][5][5];
    int dx_bfs[4] = {-1, 1, 0, 0};
    int dy_bfs[4] = {0, 0, -1, 1};
    
    void precompute_dist(bool grid[5][5]) {
        for (int i = 0; i < 5; ++i) {
            for (int j = 0; j < 5; ++j) {
                queue<pair<int, int>> q;
                for (int x = 0; x < 5; ++x)
                    for (int y = 0; y < 5; ++y)
                        dist[i][j][x][y] = -1;
                if (!grid[i][j]) continue;
                dist[i][j][i][j] = 0;
                q.emplace(i, j);
                while (!q.empty()) {
                    auto curr = q.front(); q.pop();
                    int x = curr.first, y = curr.second;
                    for (int d = 0; d < 4; ++d) {
                        int nx = x + dx_bfs[d], ny = y + dy_bfs[d];
                        if (nx >= 0 && nx < 5 && ny >= 0 && ny < 5 && grid[nx][ny] && dist[i][j][nx][ny] == -1) {
                            dist[i][j][nx][ny] = dist[i][j][x][y] + 1;
                            q.emplace(nx, ny);
                        }
                    }
                }
            }
        }
    }
    
    struct QueueNode {
        int mx, my;
        int z1x, z1y, z1hp;
        int z2x, z2y, z2hp;
        int mh;
        int step;
    };
    
    using StateKey = tuple<int, int, int, int, int, int, int, int, int>;
    
    StateKey make_key(const QueueNode& node) {
        return make_tuple(node.mx, node.my, node.z1x, node.z1y, node.z1hp, node.z2x, node.z2y, node.z2hp, node.mh);
    }
    
    void normalize_state(QueueNode& node) {
        if (node.z1hp <= 0 && node.z2hp > 0) {
            swap(node.z1x, node.z2x);
            swap(node.z1y, node.z2y);
            swap(node.z1hp, node.z2hp);
        }
        if (node.z1hp > 0 && node.z2hp > 0) {
            int pos1 = node.z1x * 5 + node.z1y;
            int pos2 = node.z2x * 5 + node.z2y;
            if (pos1 > pos2) {
                swap(node.z1x, node.z2x);
                swap(node.z1y, node.z2y);
                swap(node.z1hp, node.z2hp);
            } else if (pos1 == pos2 && node.z1hp > node.z2hp) {
                swap(node.z1hp, node.z2hp);
            }
        }
        if (node.z1hp <= 0) {
            node.z1x = 5; node.z1y = 5; node.z1hp = 0;
        }
        if (node.z2hp <= 0) {
            node.z2x = 5; node.z2y = 5; node.z2hp = 0;
        }
    }
    
    void process_action(
        int mmx, int mmy, int new_z1hp, int new_z2hp,
        int mid_z1x, int mid_z1y, int mid_z2x, int mid_z2y,
        const QueueNode& curr, queue<QueueNode>& q,
        map<StateKey, bool>& visited, bool grid[5][5],
        int zerg_dirs[4][2]
    ) {
        int nz1x = 5, nz1y = 5;
        bool is_attacker1 = false;
        if (new_z1hp > 0) {
            int zk_x = mid_z1x, zk_y = mid_z1y;
            bool adjacent = (abs(zk_x - mmx) == 1 && zk_y == mmy) || (abs(zk_y - mmy) == 1 && zk_x == mmx);
            if (adjacent) {
                nz1x = zk_x; nz1y = zk_y; is_attacker1 = true;
            } else {
                int d = dist[zk_x][zk_y][mmx][mmy];
                if (d == -1) {
                    nz1x = zk_x; nz1y = zk_y;
                } else {
                    bool moved = false;
                    for (int dir_idx = 0; dir_idx < 4; ++dir_idx) {
                        int dx = zerg_dirs[dir_idx][0], dy = zerg_dirs[dir_idx][1];
                        int nx = zk_x + dx, ny = zk_y + dy;
                        if (nx >= 0 && nx < 5 && ny >= 0 && ny < 5 && grid[nx][ny] && dist[nx][ny][mmx][mmy] == d-1) {
                            nz1x = nx; nz1y = ny; moved = true; break;
                        }
                    }
                    if (!moved) { nz1x = zk_x; nz1y = zk_y; }
                }
            }
        }
    
        int nz2x = 5, nz2y = 5;
        bool is_attacker2 = false;
        if (new_z2hp > 0) {
            int zk_x = mid_z2x, zk_y = mid_z2y;
            bool adjacent = (abs(zk_x - mmx) == 1 && zk_y == mmy) || (abs(zk_y - mmy) == 1 && zk_x == mmx);
            if (adjacent) {
                nz2x = zk_x; nz2y = zk_y; is_attacker2 = true;
            } else {
                int d = dist[zk_x][zk_y][mmx][mmy];
                if (d == -1) {
                    nz2x = zk_x; nz2y = zk_y;
                } else {
                    bool moved = false;
                    for (int dir_idx = 0; dir_idx < 4; ++dir_idx) {
                        int dx = zerg_dirs[dir_idx][0], dy = zerg_dirs[dir_idx][1];
                        int nx = zk_x + dx, ny = zk_y + dy;
                        if (nx >= 0 && nx < 5 && ny >= 0 && ny < 5 && grid[nx][ny] && dist[nx][ny][mmx][mmy] == d-1) {
                            nz2x = nx; nz2y = ny; moved = true; break;
                        }
                    }
                    if (!moved) { nz2x = zk_x; nz2y = zk_y; }
                }
            }
        }
    
        vector<pair<int, int>> attackers;
        if (new_z1hp > 0 && is_attacker1) attackers.emplace_back(mid_z1x, mid_z1y);
        if (new_z2hp > 0 && is_attacker2) attackers.emplace_back(mid_z2x, mid_z2y);
        int damage = 0;
        if (attackers.size() == 1) damage = 1;
        else if (attackers.size() == 2) damage = (attackers[0] == attackers[1]) ? 1 : 2;
    
        int new_mh = curr.mh - damage;
        if (new_mh <= 0) return;
    
        bool collision = false;
        if (new_z1hp > 0 && nz1x == mmx && nz1y == mmy) collision = true;
        if (new_z2hp > 0 && nz2x == mmx && nz2y == mmy) collision = true;
        if (collision || curr.step + 1 > 34) return;
    
        QueueNode next;
        next.mx = mmx; next.my = mmy;
        next.z1x = nz1x; next.z1y = nz1y; next.z1hp = new_z1hp;
        next.z2x = nz2x; next.z2y = nz2y; next.z2hp = new_z2hp;
        next.mh = new_mh; next.step = curr.step + 1;
        normalize_state(next);
        StateKey key = make_key(next);
        if (!visited.count(key)) {
            visited[key] = true;
            q.push(next);
        }
    }
    
    int main() {
        bool grid[5][5];
        int mx0, my0, z1x0, z1y0, z2x0, z2y0;
        for (int i = 0; i < 5; ++i) {
            string s; cin >> s;
            for (int j = 0; j < 5; ++j) {
                char c = s[j];
                grid[i][j] = (c != '1');
                if (c == 'M') { mx0 = i; my0 = j; }
                else if (c == 'Z') { z1x0 = i; z1y0 = j; }
                else if (c == 'z') { z2x0 = i; z2y0 = j; }
            }
        }
        int m, z; cin >> m >> z;
        precompute_dist(grid);
    
        queue<QueueNode> q;
        map<StateKey, bool> visited;
        QueueNode start;
        start.mx = mx0; start.my = my0;
        start.z1x = z1x0; start.z1y = z1y0; start.z1hp = z;
        start.z2x = z2x0; start.z2y = z2y0; start.z2hp = z;
        start.mh = m; start.step = 0;
        normalize_state(start);
        visited[make_key(start)] = true;
        q.push(start);
    
        int move_dirs[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};
        int zerg_dirs[4][2] = {{0,-1}, {-1,0}, {0,1}, {1,0}};
    
        while (!q.empty()) {
            QueueNode curr = q.front(); q.pop();
    
            for (int d = 0; d < 4; ++d) {
                int nmx = curr.mx + move_dirs[d][0];
                int nmy = curr.my + move_dirs[d][1];
                if (nmx < 0 || nmx >=5 || nmy <0 || nmy >=5 || !grid[nmx][nmy]) continue;
                bool conflict = false;
                if (curr.z1hp >0 && curr.z1x == nmx && curr.z1y == nmy) conflict = true;
                if (curr.z2hp >0 && curr.z2x == nmx && curr.z2y == nmy) conflict = true;
                if (conflict) continue;
    
                if (curr.z1hp <=0 && curr.z2hp <=0) {
                    cout << "WIN\n" << curr.step +1 << endl;
                    return 0;
                }
                process_action(nmx, nmy, curr.z1hp, curr.z2hp,
                              curr.z1x, curr.z1y, curr.z2x, curr.z2y,
                              curr, q, visited, grid, zerg_dirs);
            }
    
            if (curr.z1hp > 0) {
                int new_z1hp = curr.z1hp -1;
                if (new_z1hp <=0 && curr.z2hp <=0) {
                    cout << "WIN\n" << curr.step +1 << endl;
                    return 0;
                }
                process_action(curr.mx, curr.my, new_z1hp, curr.z2hp,
                              curr.z1x, curr.z1y, curr.z2x, curr.z2y,
                              curr, q, visited, grid, zerg_dirs);
            }
    
            if (curr.z2hp > 0) {
                int new_z2hp = curr.z2hp -1;
                if (curr.z1hp <=0 && new_z2hp <=0) {
                    cout << "WIN\n" << curr.step +1 << endl;
                    return 0;
                }
                process_action(curr.mx, curr.my, curr.z1hp, new_z2hp,
                              curr.z1x, curr.z1y, curr.z2x, curr.z2y,
                              curr, q, visited, grid, zerg_dirs);
            }
        }
    
        cout << "LOSE" << endl;
        return 0;
    }
    
  • 1
    @ 2015-10-24 16:32:00

    靠=-=连个sofa都拿不到=-=
    ├ 测试数据 01:答案正确... (16ms, 404KB)
    ├ 测试数据 02:答案正确... (0ms, 404KB)
    ├ 测试数据 03:答案正确... (16ms, 404KB)
    ├ 测试数据 04:答案正确... (31ms, 404KB)
    ├ 测试数据 05:答案正确... (0ms, 404KB)


    Accepted / 100 / 65ms / 404KB

  • 0
    @ 2017-03-24 01:36:57

    本题数据现在是正确的。

  • 0
    @ 2012-11-09 21:17:03

    靠,没人过得去,数据肯定有问题!建议管理员删题

  • 0
    @ 2012-11-08 21:03:15

    楼下碉堡了···

  • 0
    @ 2012-11-20 18:27:31

    ├ 测试数据 01:答案正确... (16ms, 404KB)

    ├ 测试数据 02:答案正确... (0ms, 404KB)

    ├ 测试数据 03:答案正确... (16ms, 404KB)

    ├ 测试数据 04:答案正确... (31ms, 404KB)

    ├ 测试数据 05:答案正确... (0ms, 404KB)

    ---|---|---|---|---|---|---|---|-

    Accepted / 100 / 65ms / 404KB

    数据:第一个数据是样例,2-4分别是对三种错误思想的反例数据,第五个数据是不优化会超时的数据

    抱歉,我把config.ini的fout3.txt打成了fout3,txt……

    原来因为这个错的已经过了,不是因为这个错的还是错的

  • 1

信息

ID
1766
难度
7
分类
动态规划 点击显示
标签
(无)
递交数
34
已通过
7
通过率
21%
被复制
2
上传者