信息学奥赛一本通基础算法 8 - 广度优先搜索算

1329:【例8.2】细胞

解决这个问题的思路涉及以下关键步骤:

  1. 理解题目:题目要求我们在一个数字矩阵中识别和计数由1到9数字组成的“细胞”群。一个细胞群是由相邻(上下左右)的非零数字构成的集合。需要注意的是,0不被视为细胞的一部分。

  2. 遍历矩阵:从矩阵的左上角开始,逐行遍历矩阵的每个元素。对于每个遍历到的非零元素(即细胞),检查是否已经被访问过。如果没有访问过,这意味着我们发现了一个新的细胞群。

  3. 广度优先搜索(BFS):当我们遇到一个未访问的非零元素时,使用广度优先搜索算法来遍历这个细胞群的所有成员。BFS通过将当前细胞的所有未访问邻居加入到队列中来工作,然后逐个处理队列中的元素,直到队列为空。这个过程中,每访问一个细胞,就将其标记为已访问。

    • 初始化队列:将当前未访问的细胞加入到队列中。
    • 处理队列:从队列中取出一个细胞,然后查找它的所有未访问邻居(上下左右四个方向)。对于每个未访问的邻居,将其加入队列并标记为已访问。
  4. 计数:每当通过BFS启动一次新的搜索时,这意味着我们找到了一个新的细胞群。因此,我们需要增加细胞群的计数。

  5. 避免重复:为了避免重复计算相同的细胞群,需要有一个机制来标记已经访问过的细胞。这通常通过一个与原矩阵同样大小的布尔矩阵来实现,其中true表示已访问,false表示未访问。

  6. 输出结果:完成矩阵的遍历和所有可能的BFS搜索后,输出计数的细胞群数量。

整个解决方案的核心在于广度优先搜索的有效实现,它允许我们准确地遍历和标记构成每个独立细胞群的所有细胞,从而能够准确计数。

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

struct Point {
    int x, y;
};

// 定义四个方向的一维数组
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

// 广度优先搜索
void bfs(int startX, int startY, int n, int m, vector<vector<int>>& matrix, vector<vector<bool>>& visited) {
    queue<Point> q;
    q.push({startX, startY});
    visited[startX][startY] = true;

    while (!q.empty()) {
        Point cell = q.front();
        q.pop();

        for (int i = 0; i < 4; ++i) {
            int newX = cell.x + dx[i];
            int newY = cell.y + dy[i];

            // 将isValid函数的逻辑内联到此处
            if (newX >= 0 && newX < n && newY >= 0 && newY < m && matrix[newX][newY] != 0 && !visited[newX][newY]) {
                visited[newX][newY] = true;
                q.push({newX, newY});
            }
        }
    }
}

int countCells(int n, int m, vector<vector<int>>& matrix) {
    vector<vector<bool>> visited(n, vector<bool>(m, false));
    int count = 0;

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (matrix[i][j] != 0 && !visited[i][j]) {
                bfs(i, j, n, m, matrix, visited);
                ++count; // 每次启动BFS时计数加一
            }
        }
    }

    return count;
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> matrix(n, vector<int>(m));

    // 读取输入矩阵
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            char ch;
            cin >> ch;
            matrix[i][j] = ch - '0';
        }
    }

    cout << countCells(n, m, matrix) << endl;

    return 0;
}

1330:【例8.3】最少步数

为了解决这个问题,我们可以使用广度优先搜索(BFS)来找出从两个给定的点(A 和 B)到达目标点(1,1)的最短路径。由于棋子有两种走法:“日”字形和“田”字形,我们需要考虑这两种移动方式对应的坐标变化。

“日”字形的移动可以表示为:

  • (x+2, y+1)
  • (x+2, y-1)
  • (x-2, y+1)
  • (x-2, y-1)
  • (x+1, y+2)
  • (x+1, y-2)
  • (x-1, y+2)
  • (x-1, y-2)

“田”字形的移动可以表示为:

  • (x+1, y+1)
  • (x+1, y-1)
  • (x-1, y+1)
  • (x-1, y-1)

我们可以结合这两种移动方式,对每个点执行BFS,直到到达(1,1)点。在BFS过程中,我们记录每一步的步数,并在到达(1,1)点时返回该步数作为结果。

以下是C++代码示例:

#include <bits/stdc++.h>
using namespace std;

struct Node {
    int x, y, dist;
};

int fx[12] = {-1, -2, -2, -1, 1, 2, 2, 1, -2, -2, 2, 2};
int fy[12] = {-2, -1, 1, 2, 2, 1, -1, -2, 2, -2, -2, 2};

int bfs(int s, int e) {
    // 使用vector<vector<bool>>定义vis数组,并初始化为false
    vector<vector<bool>> vis(110, vector<bool>(110, false));
    queue<Node> q;
    q.push({s, e, 0});
    vis[s][e] = true;

    while (!q.empty()) {
        Node current = q.front();
        q.pop();

        if (current.x == 1 && current.y == 1) {
            return current.dist;
        }

        for (int i = 0; i < 12; i++) {
            int tx = current.x + fx[i];
            int ty = current.y + fy[i];
            if (tx >= 1 && tx <= 100 && ty >= 1 && ty <= 100 && !vis[tx][ty]) {
                vis[tx][ty] = true;
                q.push({tx, ty, current.dist + 1});
            }
        }
    }

    return -1; // 如果无法到达(1,1),返回-1
}

int main() {
    int ax, ay, bx, by;
    // 读取A、B两点的坐标
    cin >> ax >> ay >> bx >> by;

    // 分别计算从A、B到(1,1)的最少步数并输出
    cout << bfs(ax, ay) << endl;
    cout << bfs(bx, by) << endl;

    return 0;
}

这段代码实现了从两个不同的起始点到达(1,1)点的最短路径计算。首先,我们定义了一个结构体Position来存储每个位置的坐标和到达该位置所需的步数。然后,我们通过BFS遍历棋盘,直到找到从起始点到(1,1)点的最短路径。在遍历的过程中,我们使用一个visited数组来避免重复访问同一个位置。

1248:Dungeon Master

为了解决这个三维迷宫问题并使用char类型的vector,我们首先定义迷宫的三维数组表示,然后通过广度优先搜索(BFS)找到从起点S到终点E的最短路径。下面是如何用C++实现这个解法:

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int N, M; // 全局变量,表示土地的行数和列数

// 定义表示点的结构体
struct Node {
    int x, y;
};

// 八个方向:上、下、左、右以及四个对角线方向
int dx[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};

void bfs(vector<vector<char>>& land, int x, int y) {
    queue<Node> q;
    q.push({x, y});
    land[x][y] = '.'; // 标记为已访问

    while (!q.empty()) {
        Node current = q.front();
        q.pop();

        for (int i = 0; i < 8; ++i) {
            int nx = current.x + dx[i], ny = current.y + dy[i];
            if (nx >= 0 && nx < N && ny >= 0 && ny < M && land[nx][ny] == 'W') {
                land[nx][ny] = '.'; // 标记为已访问
                q.push({nx, ny});
            }
        }
    }
}

int main() {
    cin >> N >> M;
    vector<vector<char>> land(N, vector<char>(M));
    for (int i = 0; i < N; ++i)
        for (int j = 0; j < M; ++j)
            cin >> land[i][j];

    int puddles = 0;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < M; ++j) {
            if (land[i][j] == 'W') {
                bfs(land, i, j); // 从有水的地方开始BFS
                ++puddles; // 找到一个水洼
            }
        }
    }

    cout << puddles << endl; // 输出水洼总数
    return 0;
}

这段代码首先定义了一个三维vector来表示迷宫,每个元素是一个char,代表迷宫中的一个单元格。Node结构体用于BFS中,表示当前位置和从起点到该点的距离(以分钟为单位)。bfs函数实现了广度优先搜索算法,以找到从起点到终点的最短路径。如果找到了路径,函数返回所需的最小分钟数;如果没有找到路径,则返回-1,表示被困在迷宫中。主函数读取迷宫数据,并对每组测试数据调用bfs函数,最后输出从起点到终点的最小移动次数。
dfs模板

#include <iostream>
#include <vector>
using namespace std;

int N, M; // 全局变量,表示土地的行数和列数

// 八个方向:上、下、左、右以及四个对角线方向
int dx[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};

void dfs(vector<vector<char>>& land, int x, int y) {
    land[x][y] = '.'; // 标记当前位置为已访问

    // 遍历八个方向
    for (int i = 0; i < 8; ++i) {
        int nx = x + dx[i], ny = y + dy[i];
        // 检查新位置是否在土地内,并且是否为水
        if (nx >= 0 && nx < N && ny >= 0 && ny < M && land[nx][ny] == 'W') {
            dfs(land, nx, ny); // 递归访问
        }
    }
}

int main() {
    cin >> N >> M;
    vector<vector<char>> land(N, vector<char>(M));
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < M; ++j) {
            cin >> land[i][j];
        }
    }

    int puddles = 0;
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < M; ++j) {
            if (land[i][j] == 'W') {
                dfs(land, i, j); // 从有水的地方开始DFS
                ++puddles; // 找到一个水洼
            }
        }
    }

    cout << puddles << endl; // 输出水洼总数
    return 0;
}

1250:The Castle

要使用广度优先搜索(BFS)解决这个问题,我们可以采用以下思路:

  1. 初始化:创建一个二维数组来表示城堡的每个方块是否已被访问过,以及一个表示城堡的二维数组来存储每个方块的墙的配置。

  2. 解析墙的配置:对于城堡中的每个方块,使用位运算来判断方块的四面墙是否存在。墙的配置用一个0到15的数字表示,每个位表示一面墙(例如,二进制的1011表示除东墙外的三面墙都存在)。

  3. 广度优先搜索(BFS)

    • 对于每个未被访问过的方块,使用BFS来遍历所有通过可走的路径(即没有墙阻挡的方向)相连的方块。
    • 使用队列来实现BFS。初始时,将当前方块加入队列。
    • 在BFS过程中,计算当前连通区域的大小(即房间的大小)。
    • 将遍历到的方块标记为已访问。
  4. 统计结果

    • 维护一个计数器来统计房间的总数。
    • 使用一个变量来记录遍历过程中找到的最大房间的大小。
  5. 输出结果

    • 输出房间总数和最大房间的大小。

下面是使用广度优先搜索算法解决问题的C++代码示例:

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

const int MAX = 50;
vector<vector<int>> castle(MAX, vector<int>(MAX));
vector<vector<bool>> visited(MAX, vector<bool>(MAX, false));
int m, n;

// 方向:北,东,南,西
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
int wall[4] = {2, 4, 8, 1};

int bfs(int x, int y) {
    queue<pair<int, int>> q;
    q.push({x, y});
    visited[x][y] = true;
    int area = 0;

    while (!q.empty()) {
        int cx = q.front().first;
        int cy = q.front().second;
        q.pop();
        area++;

        for (int i = 0; i < 4; ++i) {
            int nx = cx + dx[i];
            int ny = cy + dy[i];
            if (nx >= 0 && nx < m && ny >= 0 && ny < n && !visited[nx][ny] && (castle[cx][cy] & wall[i]) == 0) {
                visited[nx][ny] = true;
                q.push({nx, ny});
            }
        }
    }
    return area;
}

int main() {
    cin >> m >> n;
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            cin >> castle[i][j];
        }
    }

    int rooms = 0, maxArea = 0;
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            if (!visited[i][j]) {
                rooms++;
                maxArea = max(maxArea, bfs(i, j));
            }
        }
    }

    cout << rooms << endl;
    cout << maxArea << endl;
    return 0;
}

这段代码首先读入城堡的尺寸和每个方块的墙的配置。然后,它遍历城堡中的每个方块,对于每个未访问过的方块,使用BFS来找出所有相连的方块,计算出房间的大小。最后,输出房间的总数和最大房间的大小。

1251:仙岛求药

#include <iostream>
#include <vector>
#include <queue>
#include <cstring> // 如果需要使用memset,对于vector不必要
using namespace std;

const int MAX = 30; // 预定义的最大尺寸
vector<vector<char>> a; // 使用vector<vector<char>>代替原生数组
struct Node {
    int x, y, step;
};
int fx[4] = {0, 0, 1, -1};
int fy[4] = {1, -1, 0, 0};

int bfs(int s1, int s2, int e1, int e2) {
    queue<Node> q;
    q.push({s1, s2, 0});
    a[s1][s2] = '#'; // 标记起点为已访问
    while (!q.empty()) {
        Node current = q.front();
        q.pop();
        if (current.x == e1 && current.y == e2) {
            return current.step; // 找到终点,返回步数
        }
        for (int i = 0; i < 4; i++) {
            int tx = current.x + fx[i];
            int ty = current.y + fy[i];
            if (tx >= 0 && tx < a.size() && ty >= 0 && ty < a[0].size() && (a[tx][ty] == '.' || a[tx][ty] == '*')) { // 可以走的路径
                a[tx][ty] = '#'; // 标记为已访问
                q.push({tx, ty, current.step + 1});
            }
        }
    }
    return -1; // 无法到达终点
}

int main() {
    int n, m;
    while (cin >> n >> m && (n || m)) {
        a.resize(n, vector<char>(m)); // 使用resize为地图分配空间
        int s1, s2, e1, e2; // 起点和终点坐标
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                cin >> a[i][j];
                if (a[i][j] == '@') { // 起点
                    s1 = i;
                    s2 = j;
                }
                if (a[i][j] == '*') { // 终点
                    e1 = i;
                    e2 = j;
                }
            }
        }
        cout << bfs(s1, s2, e1, e2) << endl;
    }
    return 0;
}

1252:走迷宫

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

struct Node {
    int x, y, step;
};

// 方向数组,表示上、下、左、右四个方向的移动
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

int bfs(const vector<vector<char>>& maze, int R, int C) {
    vector<vector<bool>> visited(R, vector<bool>(C, false)); // 访问状态数组
    queue<Node> q;
    q.push({0, 0, 1}); // 从左上角开始,步数为1(包括起点)
    visited[0][0] = true;

    while (!q.empty()) {
        Node current = q.front();
        q.pop();

        // 到达右下角
        if (current.x == R - 1 && current.y == C - 1) {
            return current.step;
        }

        // 尝试四个方向的移动
        for (int i = 0; i < 4; ++i) {
            int nx = current.x + dx[i];
            int ny = current.y + dy[i];
            if (nx >= 0 && nx < R && ny >= 0 && ny < C && !visited[nx][ny] && maze[nx][ny] == '.') {
                visited[nx][ny] = true;
                q.push({nx, ny, current.step + 1});
            }
        }
    }

    return -1; // 如果无法到达终点(虽然题目保证可以到达)
}

int main() {
    int R, C;
    cin >> R >> C;
    vector<vector<char>> maze(R, vector<char>(C));
    for (int i = 0; i < R; ++i) {
        for (int j = 0; j < C; ++j) {
            cin >> maze[i][j];
        }
    }

    cout << bfs(maze, R, C) << endl;
    return 0;
}

1253:抓住那头牛

#include <iostream>
#include <queue>
#include <vector>
using namespace std;

const int MAX = 100001; // 数轴的最大范围

int bfs(int N, int K) {
    vector<int> visited(MAX, 0); // 访问数组,同时记录到达每个位置的最短时间
    queue<int> q;
    q.push(N); // 将起始位置入队
    visited[N] = 1; // 标记起始位置已访问,初始化为1而不是0,用于避免特殊情况N=0

    while (!q.empty()) {
        int current = q.front();
        q.pop();

        // 如果当前位置就是牛的位置,返回当前已经花费的时间
        if (current == K) {
            return visited[current] - 1; // 返回结果时减去初始的1
        }

        // 尝试三种移动方式
        int nextPos = current - 1;
        if (nextPos >= 0 && !visited[nextPos]) {
            visited[nextPos] = visited[current] + 1;
            q.push(nextPos);
        }

        nextPos = current + 1;
        if (nextPos < MAX && !visited[nextPos]) {
            visited[nextPos] = visited[current] + 1;
            q.push(nextPos);
        }

        nextPos = current * 2;
        if (nextPos < MAX && !visited[nextPos]) {
            visited[nextPos] = visited[current] + 1;
            q.push(nextPos);
        }
    }

    return -1; // 如果没有找到路径,返回-1(理论上不会发生,因为题目保证了解的存在)
}

int main() {
    int N, K;
    cin >> N >> K;
    cout << bfs(N, K) << endl;
    return 0;
}

1254:走出迷宫

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

const int MAXN = 100;
vector<vector<char>> maze;
vector<vector<bool>> visited;
int dx[4] = {0, 0, -1, 1}; // 上下左右移动
int dy[4] = {-1, 1, 0, 0};
int n, m; // 迷宫的行数和列数

struct Node {
    int x, y, step;
};

int bfs(int sx, int sy, int ex, int ey) {
    queue<Node> q;
    q.push({sx, sy, 0});
    visited[sx][sy] = true;
    
    while (!q.empty()) {
        Node current = q.front();
        q.pop();
        
        if (current.x == ex && current.y == ey) {
            return current.step;
        }
        
        for (int i = 0; i < 4; ++i) {
            int nx = current.x + dx[i];
            int ny = current.y + dy[i];
            
            if (nx >= 0 && nx < n && ny >= 0 && ny < m && !visited[nx][ny] && maze[nx][ny] != '#') {
                visited[nx][ny] = true;
                q.push({nx, ny, current.step + 1});
            }
        }
    }
    
    return -1; // 如果没有路径可以到达
}

int main() {
    cin >> n >> m;
    maze.resize(n, vector<char>(m)); // 使用resize为迷宫分配空间
    visited.resize(n, vector<bool>(m, false)); // 同样为访问状态分配空间
    int sx, sy, ex, ey; // 起点和终点坐标
    
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> maze[i][j];
            if (maze[i][j] == 'S') {
                sx = i;
                sy = j;
            }
            if (maze[i][j] == 'T') {
                ex = i;
                ey = j;
            }
        }
    }
    
    cout << bfs(sx, sy, ex, ey) << endl;
    return 0;
}


1255:迷宫问题

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

struct Node {
    int x, y;
    vector<pair<int, int>> path; // 记录到达该节点的路径
};

int maze[5][5]; // 迷宫矩阵
int dx[4] = {0, 0, -1, 1}; // 上下左右移动
int dy[4] = {-1, 1, 0, 0};

void bfs() {
    queue<Node> q;
    Node start = {0, 0}; // 起始点
    start.path.push_back({0, 0}); // 路径初始化
    q.push(start);
    maze[0][0] = 1; // 标记起始点为已访问

    while (!q.empty()) {
        Node current = q.front();
        q.pop();

        if (current.x == 4 && current.y == 4) { // 到达终点
            for (const auto p : current.path) { // 打印路径
                cout << "(" << p.first << ", " << p.second << ")" << endl;
            }
            return;
        }

        for (int i = 0; i < 4; ++i) {
            int nx = current.x + dx[i];
            int ny = current.y + dy[i];
            // 直接在循环中检查(nx, ny)是否是有效位置
            if (nx >= 0 && nx < 5 && ny >= 0 && ny < 5 && maze[nx][ny] == 0) {
                maze[nx][ny] = 1; // 标记为已访问
                Node next = {nx, ny, current.path};//把之前的路径给新的点 
                next.path.push_back({nx, ny}); // 将新的路径接到后面
                q.push(next);
            }
        }
    }
}

int main() {
    // 输入迷宫矩阵
    for (int i = 0; i < 5; ++i) {
        for (int j = 0; j < 5; ++j) {
            cin >> maze[i][j];
        }
    }

    bfs(); // 执行BFS搜索
    return 0;
}

1256:献给阿尔吉侬的花束

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

const int MAXR = 200, MAXC = 200;
int dx[4] = {0, 0, -1, 1}; // 上下左右移动
int dy[4] = {-1, 1, 0, 0};

struct Node {
    int x, y, step;
};

int bfs(vector<string>& maze, int R, int C, int sx, int sy, int ex, int ey) {
    vector<vector<bool>> visited(R, vector<bool>(C, false));
    queue<Node> q;
    q.push({sx, sy, 0});
    visited[sx][sy] = true;
    
    while (!q.empty()) {
        Node current = q.front(); q.pop();
        if (current.x == ex && current.y == ey) return current.step;
        
        for (int i = 0; i < 4; ++i) {
            int nx = current.x + dx[i], ny = current.y + dy[i];
            if (nx >= 0 && nx < R && ny >= 0 && ny < C && !visited[nx][ny] && maze[nx][ny] != '#') {
                visited[nx][ny] = true;
                q.push({nx, ny, current.step + 1});
            }
        }
    }
    return -1; // 如果无法到达E
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        int R, C, sx, sy, ex, ey;
        cin >> R >> C;
        vector<string> maze(R);
        for (int i = 0; i < R; ++i) {
            cin >> maze[i];
            for (int j = 0; j < C; ++j) {
                if (maze[i][j] == 'S') sx = i, sy = j;
                else if (maze[i][j] == 'E') ex = i, ey = j;
            }
        }
        
        int result = bfs(maze, R, C, sx, sy, ex, ey);
        if (result != -1) cout << result << endl;
        else cout << "oop!" << endl;
    }
    return 0;
}

1257:Knight Moves

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

struct Position {
    int x, y, step;
};

// 马的8种可能移动
int dx[8] = {-2, -2, -1, -1, 1, 1, 2, 2};
int dy[8] = {-1, 1, -2, 2, -2, 2, -1, 1};

int bfs(int L, int sx, int sy, int ex, int ey) {
    vector<vector<bool>> visited(L, vector<bool>(L, false));
    queue<Position> q;
    q.push({sx, sy, 0});
    visited[sx][sy] = true;

    while (!q.empty()) {
        Position current = q.front();
        q.pop();

        if (current.x == ex && current.y == ey) {
            return current.step;
        }

        for (int i = 0; i < 8; ++i) {
            int nx = current.x + dx[i];
            int ny = current.y + dy[i];

            if (nx >= 0 && nx < L && ny >= 0 && ny < L && !visited[nx][ny]) {
                visited[nx][ny] = true;
                q.push({nx, ny, current.step + 1});
            }
        }
    }

    return -1; // 这种情况理论上不会发生,因为题目保证了解的存在
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        int L, sx, sy, ex, ey;
        cin >> L >> sx >> sy >> ex >> ey;
        cout << bfs(L, sx, sy, ex, ey) << endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天秀信奥编程培训

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值