求序列中第k小的数_题库 | 百度数据结构 / 算法面试题型介绍及解析 第 3 期

题目1:求一个数组的最长递减子序列,比如 {9,4,3,2,5,4,3,2} 的最长递减子序列为 {9,5,4,3,2}

动态规划。

假设 0 到 i-1 这段数列的最长递减序列的长度为 s,且这些序列们的末尾值中的最大值是 t。对于 a [i] 有一下情况:

(1) 如果 a [i] 比 t 小,那么将 a [i] 加入任何一个子序列都会使 0 到 i 的最长单调序列长度变成 s+1,这样的话,在 0 到 i 的数列中,长度为 s+1 的递减子序列的末尾值最大值就是 a [i];

(2) 如果 a [i] 和 t 相等,那么说明数列从 0 项到 i 项的最长单调子序列长度就是 s;

(3) 如果 a [i] 比 t 大,那么 a [i] 就不一定能够成为长度为 s 的递减子序列的末项,这取决于长度为 s-1 的各个递减子序列的末尾值的最大值 t'。

如果 t' 比 a [i] 要大,那么就可以形成长度为 s 的递减子序列,如果 t' 比 a [i] 小,那么问题就在往前递推,把 a [i] 和长度为 s-2 的各个递减子序列的末尾值的最大值比较,直到:(1) a [i] 比长度为 s' 的递减子序列的末尾值的最大值要小,那么 a [i] 就是数列 0 到 i 部分长度为 s'+1 的递减子序列的末尾值中的最大值;(2) a [i] 比任何长度的递减子序列的末尾值的最大值都要大,那么 a [i] 就是长度为 1 的递减子序列的最大值。

所以,引入数组 c [i] 表示长度为 i 的递减子序列的末尾值的最大值。显然 c 数组必然是单调递减的。b [i] 数组用于子序列的输出,b [i] 表示从 a [0] 到 a [i] 且终止于 a [i] 的最长递减序列的长度。

算法复杂度:O (nlogn),对于数组 c 的查找使用二分查找,降低了整体的算法复杂度。

算法步骤:

1)读入 n 和 a [i].

2)将数组 c 全部赋值为 - 1.

3)定义变量 s,初始化为 1,s 表示目前为止最长单调序列的长度,同时也是数组 C 的有效容量。c [1] = a [0].

4)对于 0 到 n-1 的每个 i:

查找 c [1] 到 c [s],找到一个值 k 满足下列几种情况:

(1)c [k] <= a [i] 而 c [k-1] > a [i] (如果 k>1)

(2)找不到(1)中 k 的话,k 等于 s+1,并且 s 自加一。

c[k] = a[i];

b[i] = k;

5)最后所得 s 即为所求值。

#include//函数功能:打印最长子序列//函数参数:a为源数组,b为存放序列长度的数组,k为最长子序列的末尾元素//返回值 :无   void print(int *a, int *b, int k){  int i;  for(i=k-1; i>=0; i--){    if(a[i]>a[k] && b[k]==b[i]+1){//当满足b[i] + 1 == b[k] && a[i] > a[k]时,a[i]就是前一个元素      print(a, b, i);//递归,一直到第一个元素      break;    }   }  printf("a[%d]=%d ", k, a[k]);//从第一个满足条件的元素开始打印} //函数功能 :一个数组的最长递减子序列   //函数参数 :a指向源数组,len表示数组长度   //返回值 :无  void find_mss(int *a, int len){  int i, j, maxi=0;           //maxi用来记录最长递减序列的末尾元素     int *B = new int[len];   for(i=0; i    B[i]=1;    for(j=0;j      if(a[j]>a[i] && B[j]+1>B[i]){        B[i] = B[j]+1;        if(B[i]>B[maxi]){          maxi = i;        //更新当前找到的最长递减序列        }      }    }  }  print(a, B, maxi);} int main(){  int a[]={9,4,3,2,5,4,3,2};  int aa[]={9,8,6,5,3,5,4,2,1};  find_mss(a, 8);  printf("\n");  find_mss(aa, 9);  printf("\n");   return 0;}

题目2:输入 N 组父子对,求父子对所组成的二叉树的高度

输入 N 组数,一组数代表一个父子对(如,0 1,0 代表父节点,1 代表子节点),求这 N 组数所组成的二叉树的高度;

例如:

输入:6

    0 1

    0 2

    1 3

    1 4

    2 5

    3 6

输出:4

解题思路:动态规划法,使用一个数组 hight [N] 记录每组数所能组成的二叉树的高度,初始化为全 1 数组,使用一个数组 visited [N] 来记录每组数的访问情况,找出最优子结构:

当 visited [i]=0 时,visited [i]=1,hight [i] = hight [i]+1;

然后,当 matrix [j][0]=matrix [i][1] 且 visited [j]=0 时,hight [j] = hight [i]+1,visited [j]=1;

import java.util.Scanner;public class Main {        /**     * @param args          */    public static void main(String[] args) {                // TODO Auto-generated method stub                Scanner scanner = new Scanner(System.in);                while(scanner.hasNext()){                    int groups = scanner.nextInt();                    int[][] matrix = new int[groups][2];for(int i=0;i                    for(int j=0;j<2;j++){                    matrix[i][j] = scanner.nextInt();                }            }        //动态规划输出处理              System.out.println(maxHightHelper(matrix));                                    }    }//动态规划    public static int maxHightHelper(int[][] matrix){                if(matrix==null||matrix.length==0)                        return 0;            //记录当前组的高度        int[] hight = new int[matrix.length];                for(int i=0;i            hight[i] = 1;                  byte[] visited = new byte[matrix.length];                for(int i=0;i            if(visited[i]==0){                visited[i] = 1;                hight[i] = hight[i]+1;            }                        for(int j=i+1;j                if(matrix[j][0]==matrix[i][1]&&visited[j]==0){                    visited[j] = 1;                    hight[j] = hight[i] +1;                }            }        }                //找最大的高度        int max = 0;                for(int i=0;i            if(max                max = hight[i];        }        return max;    }}

题目3:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串 abc,则输出由字符 a、b、c 所能排列出来的所有字符串 abc、acb、bac、bca、cab 和 cba。

这是个递归求解的问题。递归算法有四个特性:(1) 必须有可达到的终止条件,否则程序将陷入死循环;(2)子问题在规模上比原问题小;(3)子问题可通过再次递归调用求解;(4)子问题的解应能组合成整个问题的解。

对于字符串的排列问题。如果能生成 n - 1 个元素的全排列,就能生成 n 个元素的全排列。对于只有 1 个元素的集合,可以直接生成全排列。全排列的递归终止条件很明确,只有 1 个元素时。下面这个图很清楚的给出了递归的过程。

1e334172e79f09374532c3d356fadf97.png

参考代码:解法 1 通过 Permutation_Solution1 (str, 0, n); 解法 2 通过调用 Permutation_Solution2 (str, str) 来求解问题。

 1 //函数功能 :求一个字符串某个区间内字符的全排列  2 //函数参数 :pStr为字符串,begin和end表示区间  3 //返回值 :无  4 void Permutation_Solution1(char *pStr, int begin, int end)  5 {  6     if(begin == end - 1) //只剩一个元素  7     {  8         for(int i = 0; i < end; i++) //打印  9             cout< 10         cout< 11     } 12     else 13     { 14         for(int k = begin; k < end; k++) 15         { 16             swap(pStr[k], pStr[begin]); //交换两个字符 17             Permutation_Solution1(pStr, begin + 1, end); 18             swap(pStr[k],pStr[begin]);  //恢复 19         } 20     } 21 } 22  23 //函数功能 :求一个字符串某个区间内字符的全排列 24 //函数参数 :pStr为字符串,pBegin为开始位置 25 //返回值 :无 26 void Permutation_Solution2(char *pStr, char *pBegin) 27 { 28     if(*pBegin == '\0') 29     { 30         cout< 31     } 32     else 33     { 34         char *pCh = pBegin; 35         while(*pCh != '\0') 36         { 37             swap(*pBegin, *pCh); 38             Permutation_Solution2(pStr, pBegin + 1); 39             swap(*pBegin, *pCh); 40             pCh++; 41         } 42     } 43 } 44 //提供的公共接口 45 void Permutation(char *pStr) 46 { 47     Permutation_Solution1(pStr, 0, strlen(pStr)); 48     //Permutation_Solution2(pStr,pStr); 49 }

题目4:输入一个字符串,输出该字符串中字符的所有组合。

举个例子,如果输入 abc,它的组合有 a、b、c、ab、ac、bc、abc。

同样是用递归求解。可以考虑求长度为 n 的字符串中 m 个字符的组合,设为 C(n,m)。原问题的解即为 C (n, 1), C (n, 2),...C (n, n) 的总和。对于求 C (n, m),从第一个字符开始扫描,每个字符有两种情况,要么被选中,要么不被选中,如果被选中,递归求解 C (n-1, m-1)。如果未被选中,递归求解 C (n-1, m)。不管哪种方式,n 的值都会减少,递归的终止条件 n=0 或 m=0。

1 //函数功能 :从一个字符串中选m个元素  2 //函数参数 :pStr为字符串, m为选的元素个数, result为选中的  3 //返回值 :无  4 void Combination_m(char *pStr, int m, vector<char> &result)  5 {  6     if(pStr == NULL || (*pStr == '\0'&& m != 0))  7         return;  8     if(m == 0) //递归终止条件  9     { 10         for(unsigned i = 0; i < result.size(); i++) 11             cout< 12         cout<<endl; 13         return; 14     } 15     //选择这个元素 16     result.push_back(*pStr); 17     Combination_m(pStr + 1, m - 1, result); 18     result.pop_back(); 19     //不选择这个元素 20     Combination_m(pStr + 1, m, result); 21 } 22 //函数功能 :求一个字符串的组合 23 //函数参数 :pStr为字符串 24 //返回值 :无 25 void Combination(char *pStr) 26 { 27     if(pStr == NULL || *pStr == '\0') 28         return; 29     int number = strlen(pStr); 30     for(int i = 1; i <= number; i++) 31     { 32         vector<char> result; 33         Combination_m(pStr, i, result); 34     } 35 }

题目5:一个射击运动员打靶,靶一共有 10 环,连开 10 枪打中 90 环的可能性有多少?

这道题的思路与字符串的组合很像,用递归解决。一次射击有 11 种可能,命中 1 环至 10 环,或脱靶。

1 //函数功能 : 求解number次打中sum环的种数 2 //函数参数 :number为打靶次数,sum为需要命中的环数,result用来保存中间结果,total记录种数 3 //返回值 :   无 4 void ShootProblem_Solution1(int number, int sum, vector<int> &result, int *total) 5 { 6     if(sum < 0 || number * 10 < sum) //加number * 10 < sum非常重要,它可以减少大量的递归,类似剪枝操作 7         return; 8     if(number == 1) //最后一枪 9     {10         if(sum <= 10) //如果剩余环数小于10,只要最后一枪打sum环就可以了11         {12             for(unsigned i = 0; i < result.size(); i++)13                 cout<' ';14             cout<endl;15             (*total)++;16             return;17         }18         else19             return;20     }21     for(unsigned i = 0; i <= 10; i++) //命中0-10环22     {23         result.push_back(i);24         ShootProblem_Solution1(number-1, sum-i, result, total); //针对剩余环数递归求解25         result.pop_back();26     }27 }28 //提供的公共接口29 void ShootProblem(int number, int sum)30 {31     int total = 0;32     vector<int> result;33     ShootProblem_Solution1(number, sum, result, &total);34     cout<<"total nums = "<endl;35 }

题目6:将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。数值为 0 或者字符串不是一个合法的数值则返回 0。

这道题要考虑全面,对异常值要做出处理。对于这个题目,需要注意的要点有:

  • 指针是否为空指针以及字符串是否为空字符串;

  • 字符串对于正负号的处理;

  • 输入值是否为合法值,即小于等于 '9',大于等于 '0';

  • int 为 32 位,需要判断是否溢出;

  • 使用错误标志,区分合法值 0 和非法值 0。

代码中用两个函数来实现该功能,其中标志位 g_nStatus 用来表示是否为异常输出,minus 标志位用来表示是否为负数。

C++:

class Solution {public:    enum Status{kValid = 0, kInValid};    int g_nStatus = kValid;    int StrToInt(string str) {        g_nStatus = kInValid;        long long num = 0;        const char* cstr = str.c_str();        // 判断是否为指针和是否为空字符串        if(cstr != NULL && *cstr != '\0'){            // 正负号标志位,默认是加号            bool minus = false;            if(*cstr == '+'){                cstr++;            }            else if(*cstr == '-'){                minus = true;                cstr++;            }            if(*cstr != '\0'){                num = StrToIntCore(cstr, minus);            }        }        return (int)num;    }private:    long long StrToIntCore(const char* cstr, bool minus){        long long num = 0;        while(*cstr != '\0'){            // 判断是否是非法值            if(*cstr >= '0' && *cstr <= '9'){                int flag = minus ? -1 : 1;                num = num * 10 + flag * (*cstr - '0');                // 判断是否溢出,32 位                if((!minus && num > 0x7fffffff) || (minus && num < (signed int)0x80000000)){                    num = 0;                    break;                }                cstr++;            }            else{                num = 0;                break;            }        }        // 判断是否正常结束        if(*cstr == '\0'){            g_nStatus = kValid;        }        return num;    }};

Python:

# -*- coding:utf-8 -*-class Solution:    def StrToInt(self, s):        # write code here        length = len(s)        if length == 0:            return 0        else:            minus = False            flag = False            if s[0] == '+':                flag = True            if s[0] == '-':                flag = True                minus = True            begin = 0            if flag:                begin = 1            num = 0            minus = -1 if minus else 1            for each in s[begin:]:                if each >= '0' and each <= '9':                    num = num * 10 + minus * (ord(each) - ord('0'))                else:                    num = 0                    break            return num

题目7:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。

例如,字符串 "+100","5e2","-123","3.1416" 和 "-1E-16" 都表示数值。但是 "12e","1a3.14","1.2.3","+-5" 和 "12e+4.3" 都不是。

表示数值的字符串遵循如下模式:

[sign]integral-digits[.[fractional-digits]][e|E[sign]exponential-digits]

其中,('[' 和 ']' 之间的为可有可无的部分)。

在数值之前可能有一个表示正负的 '+' 或者 '-'。接下来是若干个 0 到 9 的数位表示数值的整数部分(在某些小数里可能没有数值的整数部分)。如果数值是一个小数,那么在小数后面可能会有若干个 0 到 9 的数位表示数值的小数部分。如果数值用科学记数法表示,接下来是一个 'e' 或者 'E',以及紧跟着的一个整数(可以有正负号)表示指数。

判断一个字符串是否符合上述模式时,首先看第一个字符是不是正负号。如果是,在字符串上移动一个字符,继续扫描剩余的字符串中 0 到 9 的数位。如果是一个小数,则将遇到小数点。另外,如果是用科学记数法表示的数值,在整数或者小数的后面还有可能遇到 'e' 或者 'E'。

class Solution {public:    // 数字的格式可以用 A [.[B]][e|EC] 或者.B [e|EC] 表示,    // 其中 A 和 C 都是整数(可以有正负号,也可以没有)    // 而 B 是一个无符号整数    bool isNumeric(char* string){        // 非法输入处理        if(string == NULL || *string == '\0'){            return false;        }        // 正负号判断        if(*string == '+' || *string == '-'){            ++string;        }        bool numeric = true;        scanDigits(&string);        if(*string != '\0'){            // 小数判断            if(*string == '.'){                ++string;                scanDigits(&string);                if(*string == 'e' || *string == 'E'){                    numeric = isExponential(&string);                }            }            // 整数判断            else if(*string == 'e' || *string == 'E'){                numeric = isExponential(&string);            }            else{                numeric = false;            }        }        return numeric && *string == '\0';    }private:    // 扫描数字,对于合法数字,直接跳过    void scanDigits(char** string){        while(**string != '\0' && **string >= '0' && **string <= '9'){            ++(*string);        }    }    // 用来潘达 un 科学计数法表示的数值的结尾部分是否合法    bool isExponential(char** string){        ++(*string);        if(**string == '+' || **string == '-'){            ++(*string);        }        if(**string == '\0'){            return false;        }        scanDigits(string);        // 判断是否结尾,如果没有结尾,说明还有其他非法字符串        return (**string == '\0') ? true : false;    }};

题目8:求两个正整数的最大公约数。

这是一个很基本的问题,最常见的就是两种方法,辗转相除法和辗转相减法。通式分别为 f (x, y) = f (y, x% y), f (x, y) = f (y, x - y) (x >=y > 0)。根据通式写出算法不难,这里就不给出了。这里给出《编程之美》上的算法,主要是为了减少迭代的次数。

对于 x 和 y,如果 y = k * y1, x= k * x1,那么 f (x, y) = k * f (x1, y1)。另外,如果 x = p * x1,假设 p 为素数,并且 y % p != 0,那么 f (x, y) = f (p * x1, y) = f (x1, y)。取 p = 2。

//函数功能: 求最大公约数//函数参数: x,y为两个数//返回值:   最大公约数int gcd_solution1(int x, int y){  if(y == 0)    return x;  else if(x < y)    return gcd_solution1(y, x);  else  {    if(x&1) //x是奇数    {      if(y&1) //y是奇数        return gcd_solution1(y, x-y);      else    //y是偶数        return gcd_solution1(x, y>>1);    }    else //x是偶数    {      if(y&1) //y是奇数        return gcd_solution1(x>>1, y);      else    //y是偶数        return gcd_solution1(x>>1, y>>1) << 1;    }  }}

下面非递归版本:

int gcd_solution2(int x, int y){  int result = 1;  while(y)  {    int t = x;    if(x&1)    {      if(y&1)      {        x = y;        y = t % y;      }      else        y >>= 1;    }    else    {      if(y&1)        x >>= 1;      else      {        x >>= 1;        y >>= 1;        result <<= 1;      }    }  }  return result * x;}

题目9:把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数,但 14 不是,因为它包含因子 7。习惯上我们把 1 当做是第一个丑数。求按从小到大的顺序的第 N 个丑数。

所谓的一个数 m 是另一个数 n 的因子,是指 n 能被 m 整除,也就是 n% m==0。根据丑数的定义,丑数只能被 2、3 和 5 整除。根据丑数的定义,丑数应该是另一个丑数乘以 2、3 或者 5 的结果(1 除外)。因此我们可以创建一个数组,里面的数字是排好序的丑数,每一个丑数都是前面的丑数乘以 2、3 或者 5 得到的。

这个思路的关键问题在于怎样保证数组里面的丑数是排好序的。对乘以 2 而言,肯定存在某一个丑数 T2,排在它之前的每一个丑数乘以 2 得到的结果都会小于已有最大的丑数,在它之后的每一个丑数乘以乘以 2 得到的结果都会太大。我们只需要记下这个丑数的位置,同时每次生成新的丑数的时候,去更新这个 T2。对乘以 3 和 5 而言,也存在着同样的 T3 和 T5。

C++:

class Solution {public:    int GetUglyNumber_Solution(int index) {        if(index < 7){            return index;        }        vector<int> res(index);        for(int i = 0; i < 6; i++){            res[i] = i + 1;        }        int t2 = 3, t3 = 2, t5 = 1;        for(int i = 6; i < index; i++){            res[i] = min(res[t2] * 2, min(res[t3] * 3, res[t5] * 5));            while(res[i] >= res[t2] * 2){                t2++;            }            while(res[i] >= res[t3] * 3){                t3++;            }            while(res[i] >= res[t5] * 5){                t5++;            }        }        return res[index - 1];    }};

注意:1,2,3,4,5,6 都是丑数。所以当 index 小于 7 的时候,直接返回 index 即可。

Python:

# -*- coding:utf-8 -*-class Solution:    def GetUglyNumber_Solution(self, index):        # write code here        if index < 7:            return index        res = [1, 2, 3, 4, 5, 6]        t2, t3, t5 = 3, 2, 1        for i in range(6, index):            res.append(min(res[t2] * 2, min(res[t3] * 3, res[t5] * 5)))            while res[t2] * 2 <= res[i]:                t2 += 1            while res[t3] * 3 <= res[i]:                t3 += 1            while res[t5] * 5 <= res[i]:                t5 += 1        return res[index - 1]

题目10:任意数分三组,使得每组的和尽量相等.

对于本题,我们可以采用归纳总结的方法。比如,任意数组分成一组,使得每组的和尽量相等。任意的数组分成两组,使得每组的和尽量相等。从这两个基本的问题,我们容易知道,如果数组总和整除分组数的商就是分组后的和(如果可以实现的话,多数情况是接近),当然还有一个极端的情况,比如数组中的最大值,大于这个商,这时候,我们可以使用降纬的方法,把其中一个分组的值设置成这个最大值,对于剩下的值采用同样的思路。(这个使用反证法很容易证明的)

#include #include #include using namespace std;typedef vector<int> vec_int;typedef vector<vector<int> > vec_vec_int;void Output(int nNum){    cout << nNum  << " ";}void Output2(const vec_int & vecNum){    for_each(vecNum.begin(), vecNum.end(), Output);    cout << endl;}void CalZu(vec_vec_int & vecZu, int nZu, const vec_int & vecNum, int nBegin){    if (vecNum.size() <= nBegin) return;    int nSum = 0;    int nAvg = 0;    for (int i=nBegin; i        nSum += vecNum[i];    nAvg = nSum / nZu;    if (nSum % nZu != 0)        nAvg += 1;    if (nAvg < vecNum[nBegin]) {        vecZu[nZu-1].push_back(vecNum[nBegin]);        CalZu(vecZu, nZu-1, vecNum, nBegin+1);    } else {        vec_int vecSum(nZu, nAvg);        for (int i=nBegin; i            int k = 0;            int nTmpMin = vecSum[k] - vecNum[i];            for (int j=1; j                int nTmp = vecSum[j] - vecNum[i];                if ((nTmpMin < 0 && nTmp >=  0)                    || (nTmpMin < 0 && nTmpMin < nTmp)                    || (nTmp > 0 && nTmpMin > nTmp) ) {                    nTmpMin = nTmp;                    k = j;                }            }            vecZu[k].push_back(vecNum[i]);            vecSum[k] -= vecNum[i];        }    }    }int main(int argc, char ** argv){    int a[] = {9, 8, 6, 6, 6, 5, 6, 5};    // int a[] = {1003, 1002, 103, 102, 101, 3, 2, 1};    int aLen = sizeof(a) / sizeof(int);    vec_int vecNum(a, a+aLen);    sort(vecNum.begin(), vecNum.end(), greater<int>());    cout << "Input:" << endl;    for_each(vecNum.begin(), vecNum.end(), Output);     cout << endl;    const int nZu = 3;    vec_vec_int vecZu(nZu);    CalZu(vecZu, nZu, vecNum, 0);    cout << "Output:" << endl;    for_each(vecZu.begin(), vecZu.end(), Output2);    }
ba26533a04be0af66be90b5aa39a42fa.png

计算机视觉常见面试题型介绍及解答

第一期 | 第二期 | 第三期 | 第四期 | 第五期 | 

第六期 | 第七期 | 第八期 | 第九期 | 第十期 | 第11期

腾讯算法工程师笔试真题介绍及解析汇总合集

第一期 | 第二期 | 第三期 | 第四期 | 第五期 

 阿里算法岗位最新编程题介绍及解析

第一期 | 第二期 | 第三期 | 第四期 | 第五期 

第六期 | 第七期

华为研发工程师编程题型介绍及解析

第一期 | 第二期 | 第三期 | 第四期 | 第五期 |

第六期 | 第七期 | 第八期 | 第九期 | 第十期 |

字节跳动校招研发岗位笔试编程题型介绍及解析

第一期 | 第二期 | 第三期 | 第四期 | 第五期 

第六期 | 第七期 | 第八期 | 第九期 | 第十期

网易算法工程师笔试编程题型介绍及解析 

第一期 | 第二期 | 第三期 | 第四期 | 第五期

第六期 | 第七期 | 第八期 | 第九期 | 第十期

NLP 精华面试专题介绍及解析 

第一期 | 第二期 | 第三期 | 第四期 | 第五期 | 第六期

百度数据结构 / 算法面试题型介绍及解析

第一期 | 第二期

08019e8b81ff73d86f548d3588107450.png 0602918d5f8923ded3ccd2ebe0a48346.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值