又见皇后!!!

这道题算是N个皇后的拓展问题,但是这个问题需要的时间很多。


国际象棋中,皇后能攻击同一横线、同一竖线、同一斜线(45度)的敌人。

众所周知,有一个非常著名的算法问题,是求在一个n×n的国际象棋棋盘中最多能摆放多少个皇后,使其不能相互攻击。

今天我们暂且不要让问题如此理想化。假设棋盘上有一些障碍物,皇后不能摆在障碍物上,同时也不能穿过障碍物攻击别人。在此条件之下,棋盘上最多又能放多少个皇后?

                           

图中黑色方块表示障碍物,圆点表示皇后

2是一种最优摆法;图4、图5属于违规摆法

Input
输入包含多组数据。

每组数据的第一行是一个整数n1n8),表示棋盘的边长。之后的n行将描述棋盘,其中’X’表示该单元格有障碍物,’.’则表示没有。

n=0表示输入结束。

Output
对于每组数据,请输出一个整数表示最多能在棋盘上放几个皇后,使它们相互不能攻击。
每个答案占一行。


这个题看起来十分的难,怕各种的超时,但是这个题就是暴力 + 递归进行操作的,而且他的时间还是比较充足的,

所以不用那么太担心。


我的思想就是,search() 左边的变量就是把二维数组进行遍历,右边的变量就是这个符合条件的情况,

而check函数就是一个进行判断的函数,如果在横向纵向或者45度倾斜的方向有皇后就不符合条件,如果在这些

方向中碰到了X就是箱子,就不用进行判断了,直接退出,由于你的k是从0开始,而且他的方向是从

(0,0) (0,1) (0,2)...(0,num-1)的方向进行的,如果这一行遍历结束了,就进入下一行,知道k到达(num-1,num-1)

程序就结束了,由于我是这样进行设置k这个变量的,所以要通过k变量的数值,把这个二维数组的横纵坐标

计算出来,

int x = k/num

int y = k%num

这样就可以通过k的值进行计算了(k = 经过了多少个二维数组元素-1  , 因为k是在0开始的)


在判断3个方向是否有皇后的过程中,其实是可以进行一下判断的,由于我的k是从一个二维数组的(0.0) 到

这个二维数组的结尾的(num-1,num-1) 简单的说k是从上倒下,从左到右的遍历的,这样就可以省略很多次的

判断,首先是横向,判断点的左边一定是k经历过的,判断点的右边k一定没有遍历到,所以,直接就可以访问

判断点的左边就可以了,同理进行纵向的判断时刻,由于k是从上到下进行遍历的,所以你只要判断判断点的上方就

可以了,判断点的下方k还没有遍历到,判断点左边的45度只要上部分就可以了,其他的一样,原因同上,判断点右边45度只要判断右上方就可以了,其他的就不用了,原因同上。


在search()函数中我使用的是递归,判断的条件是这个位置占一个皇后或者不站一个皇后,就分成了两个部分。。。


<think>我们被要求提供N皇后问题的C++解决方案代码。根据引用内容,有几种不同的实现方法,包括回溯法和优化版本(使用位运算优化,适用于皇后数量不超过32的情况)。用户要求使用C++编写,因此我们将提供两种常的实现方式:基础回溯法和位运算优化法。 基础回溯法思路: 1. 使用一个数组`col`(或类似结构)来记录每一行皇后所在的。 2. 在放置第i行的皇后时,检查当前是否与之前放置皇后冲突(同一同一线)。 3. 如果冲突则跳过,否则放置递归处理下一行。 4. 当所有行都放置皇后,则得到一个解。 位运算优化法思路(适用于n<=32): 1. 使用三个整数(colLim, leftDiaLim, rightDiaLim)的二进制位来表示和两个方向对线的占用情况。 2. 通过位运算快速获取当前行可以放置皇后的位置。 根据引用[2]和引用[3],我们分别提供两种代码。 注意:引用[2]中的代码使用了二维数组来记录棋盘,并在搜索时同时考虑了放与不放两种情况,同时使用四个布尔数组(行、、两个对线)来记录冲突。但这种方法在搜索过程中是按每个格子(x,y)来推进的,而不是按行推进。引用[3]的代码是按行递归。 我们将提供两种常写法: 写法一:按行递归(引用[3]风格,但稍作修改,使其输出棋盘) 写法二:位运算优化(引用[1]中提到的方法,但引用[1]描述的是经典回溯,引用[2]和引用[3]没有位运算,因此我们根据位运算的经典写法补充) 由于用户要求代码,我们重点提供可运行的代码,并简要说明。 注意:输出格式要求,每个解输出n行字符串,每行n个字符,'.'表示空,'Q'表示皇后,解之间输出空行。 我们先提供按行递归的基础回溯法(输出所有解的棋盘): 这里我们参考引用[3]并修改,使其输出棋盘。引用[3]只统计解的数量,我们修改为输出所有解。 写法一:基础回溯法(输出所有解) 步骤: 1. 定义全局变量:棋盘大小n,一个数组col(记录每行皇后位置),一个容器(存储所有解,或者直接输出)。 2. 编写检查函数Place:判断当前行row的col是否可以放置(检查与前面行的冲突)。 3. 编写回溯函数:从第0行(或第1行)开始递归,如果当前行是第n行,则输出棋盘(或保存解);否则,尝试在当前行的每一放置,如果合法则递归下一行。 4. 注意回溯。 但是,输出格式要求输出棋盘,因此我们使用一个二维字符数组(或字符串数组)来构建每个解的棋盘。 然而,在递归过程中,我们不需要保存整个棋盘状态,只需要记录每行皇后位置,然后在得到一个解时,根据这个位置数组构建棋盘并输出。 因此,我们可以这样: 全局变量: vector<vector<string>> solutions; // 存储所有解(每个解是一个棋盘棋盘由vector<string>表示,每行是一个字符串) vector<int> col_placement; // 当前每行皇后位置(索引为行号) 但是,为了节省空间,我们也可以每次得到一个解就输出一个解。 我们选择在得到解时立即输出(因为n皇后解的数量可能很大,全部存储可能占用大量内存)。 代码结构: void backtrack(int row, int n) { if (row == n) { // 输出当前棋盘 print_board(col_placement, n); return; } for (int c = 0; c < n; c++) { if (is_valid(row, c, col_placement)) { col_placement[row] = c; backtrack(row+1, n); // 无需显式回溯,因为col_placement[row]会被覆盖 } } } 检查函数is_valid: bool is_valid(int row, int col, const vector<int>& col_placement) { for (int r=0; r<row; r++) { int c = col_placement[r]; if (c == col || abs(row - r) == abs(col - c)) { return false; } } return true; } 输出函数print_board: void print_board(vector<int>& col_placement, int n) { for (int i=0; i<n; i++) { string s(n, '.'); // 创建一行,初始为n个点 s[col_placement[i]] = 'Q'; cout << s << endl; } cout << endl; // 每个解后输出空行 } 但是,注意:col_placement数组的大小应为n,并我们在递归过程中使用它。 但是,这种方法在n较大时效率较低,因为检查冲突需要O(n)时间。 写法二:位运算优化(不输出所有解,但可以输出,这里我们只提供计算解数量的位运算方法,但也可以输出解,不过输出所有解时,位运算优化并不能减少解的数量,所以输出部分仍然需要时间,因此我们这里提供位运算优化求所有解并输出棋盘的方法?) 位运算优化通常用于统计解的数量,输出所有解时,位运算优化可以加速搜索过程,但输出棋盘需要额外操作。 位运算优化方法(参考经典实现): 使用三个整数:col, ld, rd,分别表示、左斜线、右斜线的占用情况(二进制位1表示被占用)。 当前行可用的位置:pos = ~(col | ld | rd) & ((1<<n)-1) (取低n位) 然后循环取可用的位置(取最低位的1:p = pos & -pos,然后从pos中移除该位置:pos -= p),并递归下一行。 但是,在递归过程中,我们如何记录每个皇后的位置?因为输出棋盘需要知道每行皇后。 我们可以用数组记录每行放置(通过计算p中1所在的位置)。 因此,我们同样需要记录每行放置(或者用栈),在到达最后一行时,根据记录输出棋盘。 位运算优化代码结构: void backtrack(int row, int col_mask, int left_diag, int right_diag, vector<int>& placement, int n) { if (row == n) { print_board(placement, n); return; } int available = ((1 << n) - 1) & ~(col_mask | left_diag | right_diag); while (available) { int pos = available & -available; // 取最低位的1 available -= pos; // 计算当前号:pos的二进制中1的位置(从0开始) int col_index = __builtin_ctz(pos); // 或者用log2,但__builtin_ctz是GCC内置函数(计算末尾0的个数,即最低位1的位置) // 记录当前行放置 placement[row] = col_index; // 递归下一行,注意更新三个掩码: // 掩码:col_mask | pos // 左斜线:(left_diag | pos) << 1 (因为下一行的左斜线影响是当前左斜线左移1位) // 右斜线:(right_diag | pos) >> 1 backtrack(row+1, col_mask | pos, (left_diag | pos) << 1, (right_diag | pos) >> 1, placement, n); } } 注意:左斜线和右斜线的更新,在递归下一行时,左斜线要左移1,右斜线要右移1(因为斜线的影响会传递到下一行)。 但是,由于左移和右移可能会超出n位,所以我们在递归时用掩码限制低位n位:通过和((1<<n)-1)相与,但这里我们在递归参数中已经用available进行了限制(因为一开始available就限制在低n位),所以移位后超出部分会被available的掩码操作过滤掉。 但是,在递归调用时,我们传入的left_diag和right_diag在下一层函数中会被available的掩码操作限制(即:available = ((1<<n)-1) & ~(col_mask | left_diag | right_diag)),所以移位后超出n位的部分会被自动忽略。 因此,我们可以这样写。 输出函数print_board同上。 但是,位运算优化只适用于n<=32(因为整数的位数限制,通常int是32位),所以当n>32时,需要改用其他方法。 由于用户没有指定n的大小,我们提供两种方法,并说明适用情况。 我们决定提供两种代码: 代码1:基础回溯法(按行递归,输出所有解) 代码2:位运算优化(输出所有解,但仅适用于n<=32) 但是,用户可能只需要一种,或者更关注通用性。考虑到基础回溯法简单易懂,n一般不会太大(通常n=8,12等),基础回溯法已经足够。 我们根据引用[4]的要求输出格式:每个方案输出n行字符串,每行n个字符,'.'和'Q',每个方案后输出空行。 我们选择基础回溯法实现,因为引用[2]和[3]都提供了基础回溯,并引用[2]的代码已经可以输出棋盘(但引用[2]的代码是按格子递归,我们这里按行递归更高效)。 因此,我们提供按行递归的基础回溯法代码(输出所有解的棋盘)。 注意:引用[2]的代码中使用了四个布尔数组(行、、两个对线)来记录冲突,这样可以将检查冲突的时间降到O(1),但需要额外空间。我们也可以采用这种方法来优化基础回溯法。 方法:使用四个数组(或三个,因为行是按行递归的,所以不会出现行冲突,只需要、主对线、副对线) 数组:bool col_used[n] -> 记录每是否被占用 主对线:bool diag1[2*n-1] -> 主对线:行号+号 = 常数,范围0~2n-2 副对线:bool diag2[2*n-1] -> 副对线:行号-号+n-1 = 常数,范围0~2n-2 这样,在放置(row, col)时,检查: if (!col_used[col] && !diag1[row+col] && !diag2[row-col+n-1]) 则合法。 然后标记: col_used[col] = diag1[row+col] = diag2[row-col+n-1] = true; 递归下一行 递归返回后,回溯:col_used[col] = diag1[row+col] = diag2[row-col+n-1] = false; 这种方法比显式循环检查冲突更快。 因此,我们采用这种优化。 代码结构: 全局(或作为参数传递): vector<bool> col_used; vector<bool> diag1; // 主对线 vector<bool> diag2; // 副对线 vector<int> queens; // 每行皇后放在哪一,用于最后输出棋盘(也可以不用,因为递归时我们按行放置,可以直接用栈) 函数: void solve(int row, int n, vector<string>& current, vector<vector<string>>& solutions) 或者直接输出,不存储(这里我们直接输出) 但是,输出所有解时,如果解的数量很大,直接存储可能内存不够,所以选择直接输出。 因此,我们这样: void backtrack(int row, int n, vector<int>& placement, vector<bool>& col_used, vector<bool>& diag1, vector<bool>& diag2) { if (row == n) { print_board(placement, n); return; } for (int col=0; col<n; col++) { int d1 = row + col; int d2 = row - col + n - 1; if (!col_used[col] && !diag1[d1] && !diag2[d2]) { placement[row] = col; col_used[col] = diag1[d1] = diag2[d2] = true; backtrack(row+1, n, placement, col_used, diag1, diag2); col_used[col] = diag1[d1] = diag2[d2] = false; // 回溯 } } } 初始化: vector<int> placement(n, -1); // 每行皇后位置 vector<bool> col_used(n, false); vector<bool> diag1(2*n-1, false); vector<bool> diag2(2*n-1, false); 然后调用:backtrack(0, n, placement, col_used, diag1, diag2); 输出函数print_board(placement, n)同上。 考虑到引用[2]的代码中使用了二维棋盘,并是逐格递归,我们这里按行递归效率更高(因为每行只放一个皇后)。 因此,我们最终选择这种优化后的基础回溯法(使用三个布尔数组避免显式检查冲突)。 下面提供完整代码(注意:输出格式,每行末尾不能有空格,每个解后有空行)。 代码: 注意:我们直接输出每个解,不存储。 但是,如果用户需要存储(比如返回所有解),可以修改,但题目要求输出棋盘。 我们按照要求输出。 注意:皇后数量n由用户输入。 完整代码: #include <iostream> #include <vector> #include <cmath> #include <cstdlib> using namespace std; void print_board(vector<int>& placement, int n) { for (int i=0; i<n; i++) { string s(n, '.'); s[placement[i]] = 'Q'; cout << s << endl; } cout << endl; // 每个解后输出空行 } void backtrack(int row, int n, vector<int>& placement, vector<bool>& col_used, vector<bool>& diag1, vector<bool>& diag2) { if (row == n) { print_board(placement, n); return; } for (int col=0; col<n; col++) { int d1 = row + col; int d2 = row - col + n - 1; // 防止负数,所以加n-1 if (!col_used[col] && !diag1[d1] && !diag2[d2]) { placement[row] = col; col_used[col] = true; diag1[d1] = true; diag2[d2] = true; backtrack(row+1, n, placement, col_used, diag1, diag2); col_used[col] = false; diag1[d1] = false; diag2[d2] = false; } } } int main() { int n; cout << "请输入皇后的数量: "; cin >> n; vector<int> placement(n, -1); // 记录每行的皇后所在 vector<bool> col_used(n, false); vector<bool> diag1(2*n-1, false); vector<bool> diag2(2*n-1, false); backtrack(0, n, placement, col_used, diag1, diag2); return 0; } 但是,注意:这个代码没有考虑没有任何解的情况,但也会正常输出(不输出任何棋盘,因为backtrack返回后程序结束)。这是符合要求的。 然而,引用[2]的代码中,在放置皇后时,不仅考虑放,还考虑不放?实际上按行递归不需要考虑不放,因为每行必须放一个皇后。所以我们的循环中,如果找到合法位置就放,否则循环结束就回溯到上一行。 另外,我们也可以像引用[2]那样,在递归函数中同时处理不放的情况?不需要,因为每行必须放一个皇后,所以我们在当前行找到合法放置即可,没有不放的选项。 因此,我们的代码是合理的。 但是,我们也可以使用非递归方式,但这里使用递归更清晰。 最后,我们提供这个代码。 另外,位运算优化的代码,如果需要,我们也可以提供,但考虑到通用性,我们先提供基础回溯法。 如果用户需要位运算优化,我们可以补充。 因此,我们回答: 我们提供两种C++实现方法,第一种是基础回溯法(使用布尔数组优化冲突检查),第二种是位运算优化(适用于n<=32)。 由于用户要求代码,我们分别提供。 方法一:基础回溯法(使用布尔数组优化) 方法二:位运算优化回溯 我们分别提供代码。 方法一代码(已提供,上)但为了完整,我们再次整理。 方法二:位运算优化(输出所有解) 注意:位运算优化在输出所有解时,也需要记录每行皇后位置,以便输出棋盘。 代码: #include <iostream> #include <vector> using namespace std; void print_board(vector<int>& placement, int n) { for (int i=0; i<n; i++) { string s(n, '.'); s[placement[i]] = 'Q'; cout << s << endl; } cout << endl; } void backtrack(int row, int col_mask, int left_diag, int right_diag, vector<int>& placement, int n) { if (row == n) { print_board(placement, n); return; } // 计算可用的位置:col_mask, left_diag, right_diag 的二进制位1表示不可用 int available = ((1 << n) - 1) & ~(col_mask | left_diag | right_diag); while (available) { int pos = available & -available; // 取最低位的1 available ^= pos; // 或者 available -= pos; 清除最低位的1 // 计算索引:从0开始,计算pos的二进制中1的位置(即末尾0的个数) int col_index = __builtin_ctz(pos); // 使用GCC内置函数,注意:如果使用其他编译器,可能需要替换为其他函数 // 记录当前行放置 placement[row] = col_index; // 递归下一行,更新三个掩码: // 掩码:col_mask | pos // 左斜线:(left_diag | pos) << 1 // 右斜线:(right_diag | pos) >> 1 backtrack(row+1, col_mask | pos, (left_diag | pos) << 1, (right_diag | pos) >> 1, placement, n); } } int main() { int n; cout << "请输入皇后的数量: "; cin >> n; vector<int> placement(n, -1); // 记录每行皇后位置 // 初始调用:从第0行开始,掩码、左斜线掩码、右斜线掩码都为0 backtrack(0, 0, 0, 0, placement, n); return 0; } 注意:位运算优化代码使用了GCC内置函数__builtin_ctz(返回二进制中末尾0的个数,即从最低位开始的1的位置)。在非GCC编译器下可能无法编译,可以替换为: int col_index = 0; int temp = pos; while (temp >>= 1) col_index++; // 但是这样计算的是最高位?不对,应该计算最低位的1的位置。 // 另一种方法:使用log2(pos)(但pos必须是2的幂次) if (pos > 0) { col_index = log2(pos); // 这样得到的是指数,即位置(从0开始) } 但是,log2函数在cmath中,可能有浮点误差,但pos是2的幂,所以可以。 因此,可以替换为: int col_index = log2(pos); // 需要#include <cmath> 但是,注意:log2函数在pos很大时(比如超过2^30)可能会有精度问题,但n<=32,所以pos最大为2^31(在32位系统上,n=32时,pos可以是2^31,但log2(2^31)=31,没问题)。 修改后的代码(可移植): int col_index = (int)log2(pos); // 强制转换为int 或者,使用循环(效率较低,但n小没关系): int col_index = 0; int p = 1; while ((pos & p) == 0) { col_index++; p <<= 1; } // 这样col_index就是最低位1的位置?不对,这样得到的是从最低位开始数0的个数,但循环中我们每次左移p,当p与pos匹配时,col_index就是0的个数,也就是位置。 // 但这样写有点麻烦,不如用log2。 因此,我们使用log2。 修改位运算优化代码中的行: int col_index = (int)log2(pos); // 注意:pos是2的幂,所以log2(pos)是整数 但是,注意:log2(pos)返回double,我们转换为int,并pos必须大于0。 完整位运算优化代码(使用log2): #include <iostream> #include <vector> #include <cmath> using namespace std; void print_board(vector<int>& placement, int n) { for (int i=0; i<n; i++) { string s(n, '.'); s[placement[i]] = 'Q'; cout << s << endl; } cout << endl; } void backtrack(int row, int col_mask, int left_diag, int right_diag, vector<int>& placement, int n) { if (row == n) { print_board(placement, n); return; } int available = ((1 << n) - 1) & ~(col_mask | left_diag | right_diag); while (available) { int pos = available & -available; available ^= pos; // 或者 available -= pos; // 计算索引:log2(pos) int col_index = (int)log2(pos); // 注意:pos必须是2的幂,大于0 placement[row] = col_index; // 递归 backtrack(row+1, col_mask | pos, (left_diag | pos) << 1, (right_diag | pos) >> 1, placement, n); } } int main() { int n; cout << "请输入皇后的数量: "; cin >> n; if (n > 32 || n < 1) { cout << "位运算优化仅适用于1<=n<=32" << endl; return 0; } vector<int> placement(n, -1); backtrack(0, 0, 0, 0, placement, n); return 0; } 注意:位运算优化代码中,我们限制了n的范围(1~32),因为当n>32时,整数位不够(我们使用int,通常32位)。如果n=0,则没有意义。 最后,我们提供两种代码,用户可以根据需要选择。 但是,用户可能只需要一种。我们根据常情况,先提供基础回溯法(方法一),因为它更通用(对n没有限制,但n太大时解的数量指数级增长,输出会非常慢,但代码可以运行)。 因此,我们最终提供基础回溯法(布尔数组优化)的代码作为主要答案,位运算优化作为补充。 另外,引用[2]的代码是逐格递归,我们这里按行递归效率更高,所以不采用逐格递归。 最终答案: 我们提供使用C++解决N皇后问题的代码,采用回溯法并使用布尔数组优化冲突检查,直接输出所有解的棋盘。 代码如下:</think>以下是使用C++实现的N皇后问题解决方案代码,采用回溯法并优化了冲突检查(使用布尔数组记录和对线占用情况),能输出所有解的棋盘布局: ```cpp #include <iostream> #include <vector> using namespace std; // 打印棋盘布局 void print_board(vector<int>& queens, int n) { for (int i = 0; i < n; i++) { string row(n, '.'); // 初始化一行,全为'.' row[queens[i]] = 'Q'; // 在皇后位置标记'Q' cout << row << endl; } cout << endl; // 解之间用空行分隔 } // 回溯法求解N皇后 void backtrack(int row, int n, vector<int>& queens, vector<bool>& col_used, vector<bool>& diag1, vector<bool>& diag2) { if (row == n) { print_board(queens, n); // 找到解,打印棋盘 return; } for (int col = 0; col < n; col++) { int d1 = row + col; // 主对线索引 int d2 = row - col + n - 1; // 副对线索引(防负数) // 检查当前位置是否安全 if (!col_used[col] && !diag1[d1] && !diag2[d2]) { queens[row] = col; // 记录皇后位置 col_used[col] = diag1[d1] = diag2[d2] = true; // 标记占用 // 递归处理下一行 backtrack(row + 1, n, queens, col_used, diag1, diag2); // 回溯:撤销标记 col_used[col] = diag1[d1] = diag2[d2] = false; } } } int main() { int n; cout << "请输入皇后的数量: "; cin >> n; vector<int> queens(n, -1); // 记录每行皇后位置 vector<bool> col_used(n, false); // 占用标记 vector<bool> diag1(2 * n - 1, false); // 主对线占用标记 vector<bool> diag2(2 * n - 1, false); // 副对线占用标记 backtrack(0, n, queens, col_used, diag1, diag2); return 0; } ``` ### 代码说明: 1. **冲突检查优化**: - **冲突**:`col_used`数组标记已被占用的。 - **主对线**:`diag1`数组标记行号+号相同的对线(索引范围:$0$ 到 $2n-2$)。 - **副对线**:`diag2`数组标记行号-号相同的对线(索引范围:$0$ 到 $2n-2$),通过 `row-col+n-1` 避免负数索引。 2. **输出格式**: - 每个解输出 $n$ 行字符串(如 `..Q.`)。 - 解之间用空行分隔,符合题目要求[^4]。 3. **时间复杂度**: - 最坏情况 $O(n!)$,但优化后实际运行效率显著高于朴素回溯法。 ### 使用示例: 输入 `4` 将输出: ``` .Q.. ...Q Q... ..Q. ..Q. Q... ...Q .Q.. ``` ### 相关问题: 1. 如何优化N皇后问题的时间复杂度? 2. 位运算在N皇后问题中如何应用? 3. N皇后问题有哪些实际应用场景? 4. 当皇后数量极大(如 $n>30$)时,如何高效统计解的数量? [^1]: 回溯法通过递归尝试所有可能性,当冲突发生时撤销操作(回溯)。 [^2]: 布尔数组将冲突检查复杂度从 $O(n)$ 降至 $O(1)$。 [^3]: 对线索引公式确保唯一标识每条对线。 [^4]: 输出格式要求每个解独立显示,解间有空行。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值