牛客网 NOIP/CSP 真题班

本文探讨了立体图的绘制方法,通过坐标系映射和覆盖规则,实现了三维积木堆叠的二维图形表示。此外,深入研究了高精度计算在麦森数计算中的应用,包括位数计算及最后500位的精确展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

15.1 普及组5-字符串处理

第4节 立体图

 小渊是个聪明的孩子,他经常会给周围的小朋友们讲些自己认为有趣的内容。最近,他准备给小朋友们讲解立体图,请你帮他画出立体图。
小渊有一块面积为m*n的矩形区域,上面有m*n个边长为1的格子,每个格子上堆了一些同样大小的吉姆(积木的长宽高都是1),小渊想请你打印出这些格子的立体图。我们定义每个积木为如下格式,并且不会做任何翻转旋转,只会严格以这一种形式摆放:

每个顶点用1个加号’+’表示,长用3个”-“表示,宽用1个”/”表示,高用两个”|”表示。字符’+’,‘-‘,’/’,‘|’的ASCII码分别为43,45,47,124。字符’.’(ASCII码46)需要作为背景输出,即立体图里的空白部分需要用’.’代替。立体图的画法如下面的规则:

若两块积木左右相邻      若两块积木上下相邻       若两块积木前后相邻
图示为:                图示为:                 图示为:

                    

立体图中,定义位于第(m,1)的格子(即第m行第1列的格子)上面自底向上的第一块积木(即最下面的一块积木)的左下角顶点为整张图最左下角的点。

 

输入描述:

第一行有用空格隔开的两个整数m和n,表示有m*n个格子(1 ≤ m,n ≤ 50)。
接下来的m行,是一个m*n的矩阵,每行有n个用空格隔开的整数,其中第i行第j列上的整数表示第i行第j列的格子上摞有多少个积木(1 ≤ 每个格子上的积木 ≤ 100)。


 

输出描述:

题目要求的立体图,是一个K行L列的字符矩阵,其中K和L表示最少需要K行L列才能按规定输出立体图。

示例1

输入

3 4
2 2 1 2
2 2 1 1
3 2 1 2

输出

......+---+---+...+---+
..+---+  /   /|../   /|
./   /|-+---+ |.+---+ |
+---+ |/   /| +-|   | +
|   | +---+ |/+---+ |/|
|   |/   /| +/   /|-+ |
+---+---+ |/+---+ |/| +
|   |   | +-|   | + |/.
|   |   |/  |   |/| +..
+---+---+---+---+ |/...
|   |   |   |   | +....
|   |   |   |   |/.....
+---+---+---+---+......

乍一看很恶心,但是实际考察内容并不难的吓人题。

解题:对于立体图形,很重要的一点就是建立坐标系。首先观察题中所给的三个基本图形(左右,上下,前后相邻),可以看出,右边的覆盖左边的,上面的覆盖下面的,前面的覆盖后面的,于是我们可以按照下图方式进行建系:

于是覆盖规则变为,Y值大的覆盖Y值小的(右边覆盖左边),Z值大的覆盖Z值小的(上面覆盖下面),X值大的覆盖X值小的(前面覆盖后面)。可知在我们想从立体图映射到平面图的时候必须按照X、Y、Z各自从大到小的顺序进行覆盖,X、Y、Z之间的顺序无影响。问题简化为,已经立体方块的摆放,根据题意确定映射规则,在平面图中绘出该图形。为方便构图,我们需要设立一个定点,并且将图纸设置的足够大。题解中,我们设图纸为500*500,(题解中声明经验算,图形最大不会超过400*400,保险起见设置了500*500),并以整体图形的最底最左最前的方块为基准点。

题面中给的是m*n的高度为g[i][j]的方块摆放数据图,抽象出每一个方块的数据表示为(x,y,z),表示该方块处在X方向上第x层,Y方向上第y层,Z方向上第z层的方块。现在需要一个映射规则将其放置到平面图上,我们取方块的左下前方块为每一个方块映射的基准点进行映射,取此点对于x和y的坐标都比较容易确立,映射完之后我们就把写好的box涂上去即可。

                    

我们根据三个基本图来确立映射点的坐标:

A.Y坐标变化不会改变X和Z坐标

B.Z坐标变化会导致X坐标变化,设Z变化了Δ,则X变化量为-3*Δ。(3是直接数第二个图两个立方体x坐标的差得到)

C.X坐标变化会导致Y坐标变化,设Z变化了Δ,则Y变化量为+4*Δ。(4是直接数第二个图两个立方体y坐标的差得到)

增量正负号的确立是由于我们是按照X从小到大,Z从小到达的顺序进行放置的,第二个图中上面的立方体后放,第三个图中前面的立方体后放。

所有变化的基准方块为(499,0,0)处的方块,在放置时记得更新当前能到到达的上边界和右边界(左边界天然固定为0,下边界根据该算法直接固定在图纸的底面)。

剩余最后一个问题就是如何涂这个box,我们直接将左下角的点通过(x-5,y-0)对应到整个box的开始点(0,0),然后遇到box的点不为'.'即为有用数据的时候进行填涂即可。

#include<iostream>
using namespace std;

char box[6][8]={
    "..+---+",
    "./   /|",
    "+---+ |",
    "|   | +",
    "|   |/.",
    "+---+..",
};//一个立方体在平面中的投影

//本题采取对立方块进行定位的操作  (x,y,z)表示 x方向第x层 y方向第y层 z方向第z层 取方块的左下前的点为定位点
//由题目中三个基本图形可以看出 在立体图中改变x会导致投影到[x,y]面的坐标x和y的改变,改变y则只改变投影坐标的y,改变z则只改变投影坐标的z
const int N=500;
int n,m;
char ch[N][N];
int g[N][N];

int main(){
    cin>>n>>m;
    int i,j,x,y,z,X,Y,up=N,right=0;
    
    for(i=0;i<n;++i){
        for(j=0;j<m;++j){
            cin>>g[i][j];
        }
    }
    
    for(i=0;i<N;++i){
        for(j=0;j<N;++j){
            ch[i][j]='.';
        }
    }
    
    for(x=0;x<n;++x){
        for(y=0;y<m;++y){
            for(z=0;z<g[x][y];++z){
                
                X=499-(n-1-x)*2-3*z;
                Y=4*y+(n-1-x)*2;
                
                up=min(up,X-5);//获得实际填入二维平面的图形的上边界
                right=max(right,Y+6);//获得实际填入二维平面的图形的右边界
                //获得投影点
                for(i=0;i<6;++i){
                    for(j=0;j<7;++j){
                        if(box[i][j]!='.'){
                            ch[X-5+i][Y+j]=box[i][j];
                        }
                    }
                }
            }
        }
    }
    
    for(i=up;i<N;++i){
        for(j=0;j<=right;++j)
            cout<<ch[i][j];
        cout<<endl;
    }
    
}
  •  

17.1 普及组7-数学

第2节 麦森数

形如2P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个素数,2P-1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要应用,它与完全数密切相关。

任务:输入P(1000<P<3100000),计算2P-1的位数和最后500位数字(用十进制高精度数表示)

输入描述:

只包含一个整数P(1000<P<3100000)

输出描述:

第一行:十进制高精度数2P-1的位数。

第2-11行:十进制高精度数2P-1的最后500位数字。(每行输出50位,共输出10行,不足500位时高位补0)

不必验证2P-1与P是否为素数。

示例1

输入

1279

输出

386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000104079321946643990819252403273640855
38615262247266704805319112350403608059673360298012
23944173232418484242161395428100779138356624832346
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
50138443826029173234888531116082853841658502825560
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087

吓人题再次石锤->->,首先来看第一问,求位数,实际上就是求log10(2^p-1)+1,首先p的范围最大可以到300w,乍一看无法计算,但是2的次幂有个特点就是末位只有2、4、8、6四种情况,用他们减去1并不会有借位发生,即2^p与2^p-1的位数是相同的,于是答案变为log10(2^p)+1,利用对数运算的性质变为plog10(2)+1。

第二问就是一个高精度计算罢了,学习一波人家的高精度:由于要求最后500位,利用快速幂的复杂度变为500*500*log2(p)。

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;

const int N=510;

int res[N],a[N],c[N];

void mul(int res[],int a[],int b[]){
    int i,j;
    memset(c,0,sizeof(c));
    for(i=0;i<N;++i){
        for(j=0;i+j<N&&j<N;++j){
            c[i+j]+=a[i]*b[j];
        }
    }
    for(i=0,j=0;i<N;++i){ //处理进位
        j+=c[i];
        res[i]=j%10;
        j/=10;
    }
}

void qmi(int p){
    res[0]=1;
    a[0]=2;
    while(p){ 
        if(p&1)mul(res,res,a);   //res=res*a;
        mul(a,a,a);  //a=a*a;
        p>>=1;
    }
}

int main(){
    int p,i,j;
    cin>>p;
    cout<<(int)(p*log10(2))+1<<endl;
    qmi(p);
    --res[0];
    for(j=499;j>=0;j--){
        cout<<res[j];
        if(j%50==0)cout<<endl;
    }
    return 0;
}
  •  

第1章 7月22日提高组1-模拟

第2节 时间复杂度

给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序,于是你的机会来啦!下面请你编写程序来判断小明对他的每个程序给出的时间复杂度是否正确。 A++ 语言的循环结构如下:
F i x y
循环体
E
然后判断 i 和 y 的大小关系,若 i 小于等于 y 则进入循环,否则不进入。每次循环结束后i都会被修改成 i +1,一旦 i 大于 y 终止循环。 x 和 y 可以是正整数(x 和 y 的大小关系不定)或变量 n。n 是一个表示数据规模的变量,在时间复杂度计算中需保留该变量而不能将其视为常数,该数远大于 100。 `E`表示循环体结束。循环体结束时,这个循环体新建的变量也被销毁。
注:本题中为了书写方便,在描述复杂度时,使用大写英文字母 O 表示通常意义下  的概念。

输入描述:

输入文件第一行一个正整数 t,表示有 t(t≤ 10) 个程序需要计算时间复杂度。
每个程序我们只需抽取其中 `F i x y`和`E`即可计算时间复杂度。注意:循环结构允许嵌套。 
接下来每个程序的第一行包含一个正整数 L 和一个字符串,L 代表程序行数,字符串表示这个程序的复杂度,`O(1)`表示常数复杂度,`O(n^w)` 表示复杂度为 nw,其中 w 是一个小于 100 的正整数(输入中不包含引号),输入保证复杂度只有 `O(1)` 和 `O(n^w)` 两种类型。 
接下来 L 行代表程序中循环结构中的 `F i x y` 或者 `E`。 程序行若以 `F` 开头,表示进入一个循环,之后有空格分离的三个字符(串)`i x y`,其中 i 是一个小写字母(保证不为 `n` ),表示新建的变量名,x 和 y 可能是正整数或 `n` ,已知若为正整数则一定小于 100。  程序行若以 `E`开头,则表示循环体结束。

输出描述:

输出文件共 t 行,对应输入的 t 个程序,每行输出`Yes`或`No`或者`ERR`,若程序实际复杂度与输入给出的复杂度一致则输出 `Yes`,不一致则输出`No`,若程序有语法错误(其中语法错误只有: ①F 和 E 不匹配 ②新建的变量与已经存在但未被销毁的变量重复两种情况),则输出`ERR`。
注意:即使在程序不会执行的循环体中出现了语法错误也会编译错误,要输出`ERR`。

示例1

输入

8
2 O(1)
F i 1 1
E
2 O(n^1)
F x 1 n
E
1 O(1)
F x 1 n
4 O(n^2)
F x 5 n
F y 10 n
E
E
4 O(n^2)
F x 9 n
E
F y 2 n
E
4 O(n^1)
F x 9 n
F y n 4
E
E
4 O(1)
F y n 4
F x 9 n
E
E
4 O(n^2)
F x 1 n
F x 1 10
E
E

输出

Yes
Yes
ERR
Yes
No
Yes
Yes
ERR

说明

第一个程序 i 从1 到 1 是常数复杂度。
第二个程序 x 从 1 到 n 是 n 的一次方的复杂度。
第三个程序有一个 `F` 开启循环却没有E结束,语法错误。
第四个程序二重循环,n 的平方的复杂度。
第五个程序两个一重循环,n 的一次方的复杂度。
第六个程序第一重循环正常,但第二重循环开始即终止(因为 n 远大于 100,100 大于 4)。
第七个程序第一重循环无法进入,故为常数复杂度。
第八个程序第二重循环中的变量 x 与第一重循环中的变量重复,出现语法错误②,输出 `ERR`。

 

备注:

对于 30% 的数据:不存在语法错误,数据保证小明给出的每个程序的前 L/2 行一定为以 `F` 开头的语句,第 L/2+1 行至第 L 行一定为以 `E` 开头的语句,L≤ 10,若 x,y 均为整数,x 一定小于 y,且只有 y 有可能为 `n`。
对于 50% 的数据:不存在语法错误,L≤ 100,且若 x,y 均为整数,x 一定小于 y,且只有 y 有可能为 `n`。
对于 70% 的数据:不存在语法错误,L≤ 100。
对于 100% 的数据:t≤ 10,L≤ 100。若 x,y 均为整数,x 一定小于 y,且只有 y 有可能为 `n`。

首先对于循环结构,For和End的匹配,自然可以借助括号匹配的方法,用栈结构,剩下需要的就是计算最高次的复杂度。

对于循环结构,我们知道:

A.如果当前层不能执行,那么嵌套在它之内的所有层都不能正常执行。

B.每嵌套一层可以正常执行的层,时间复杂度就会变为外层的所有复杂度×当前层的运算复杂度。

为了方便表示,我们用n^x次方中的x表示每层的复杂度,这样计算总体复杂度的时候,只需要对x进行加减运算即可。

另外,为了实现对变量名的探测,而这题规定了变量名只会是小写字母,我们开一个30大小的bool数组用于标记出现情况。

具体算法,首先初始化一个栈,结构为pair<char,int>型,用于表示当前层的变量以及当前程序运行到当前层时能到达的复杂度的指数。

对每一个For做如下操作:

1.如果变量名发生冲突,则程序发生错误,后续只需要将该次的输入数据读空而不进行任何操作

2.否则计算当前层的运算量:

如果当前层是可执行层,如果栈顶层也可以执行,将本层的指数加上栈顶元素的复杂度指数作为程序运行到当前层能到达的复杂度,将当前层压入栈。如果栈顶层不可执行,表示当前层是嵌套在一个不可执行的层里的,应该将当前层设置为不可执行,将当前层压入栈。我们用复杂度指数为-1表示不可执行。

如果当前层不可执行(x>y),那么压入栈。

最后记得更新一下最大的复杂度指数并把所使用的变量进行标记。

对每一个End做如下操作:

1.如果需要弹栈时栈空,发生错误,后续只读不操作。

2.否则从栈中弹出元素,并把变量名标记为可用。

#include<iostream>
#include<string>
#include<cstring>
#include<sstream>
using namespace std;
typedef pair<char,int> Time;   //局部变量名  截至目前层的时间复杂度

const int N=110;

bool exist[30];
Time stack[N];  //栈结构
int tt;   //栈顶指针,为便于程序涉及,数组角标为0之处表示复杂度为n^0,表示循环所在的程序执行一次 

int string_to_number(string str){
    int i,n=str.length(),ans=0;
    for(i=0;i<n;++i){
        ans=ans*10+str[i]-'0';
    }
    return ans;
}

int get_time(string str){  //计算给出的复杂度
    if(str=="O(1)")return 0;
    int t=str.find("^");
    string number=str.substr(t+1);
    number.pop_back();
    return string_to_number(number);
}

int compute_time(string x,string y){  // 计算当前层的运算量 
    if(x=="n"){
        if(y=="n") return 0;
        return -1;
    }
    if(y=="n"){
        return 1;
    }
    int a=string_to_number(x),b=string_to_number(y);
    if(a<=b)return 0;
    return -1;
}

int main(){
    int T,n,O,maxTime,time;
    bool error;
    string str,F,i,x,y;
    cin>>T;
    while(T--){
        cin>>n>>str;  //语句和复杂度
        O=get_time(str);
        
        getline(cin,str);//读掉多余的换行
        
        maxTime=0,error=false,tt=0;
        memset(exist,false,sizeof(exist));
        
        while(n--){
            getline(cin,str);
            
            if(error)continue;//有错误发生 直接读取但不操作
            
            if(str=="E"){
                if(!tt){ //栈空还要弹 显然语法错误 
                	//cout<<"循环bug"<<endl;
                	error=true;
                }
                else{
                	exist[stack[tt].first-'a']=false;
                	--tt;
                }
            }
            
            else{
                stringstream stream(str);
                stream>>F>>i>>x>>y;
                if(exist[i[0]-'a']){
                	//cout<<"变量bug"<<endl;
                	error=true;  //已经有了该变量
                }
                else{
                    time=compute_time(x,y);
                    if(time>=0&&stack[tt].second>=0){
                        time=time+stack[tt].second;
                        maxTime=max(maxTime,time);
                    }else{
                    	time=-1;
                    }
                    stack[++tt]=Time{i[0],time}; 
                    exist[i[0]-'a']=true;
                }
                
            }
            
        }
        if(tt)error=true;
        if(error)cout<<"ERR"<<endl;
        else if(maxTime==O)cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}
  •  

第5节 侦探推理(毒瘤题)

明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏。游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯。接着,明明逐个询问每一个同学,被询问者可能会说:

证词中出现的其他话,都不列入逻辑推理的内容。

明明所知道的是,他的同学中有N个人始终说假话,其余的人始终说真。

现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,请记住,凶手只有一个!

输入描述:

输入由若干行组成,第一行有二个整数,M(1≤M≤20)、N(1≤N≤M)和P(1≤P≤100);M是参加游戏的明明的同学数,N是其中始终说谎的人数,P是证言的总数。接下来M行,每行是明明的一个同学的名字(英文字母组成,没有主格,全部大写)。
往后有P行,每行开始是某个同学的名宇,紧跟着一个冒号和一个空格,后面是一句证词,符合前表中所列格式。证词每行不会超过250个字符。
输入中不会出现连续的两个空格,而且每行开头和结尾也没有空格。

输出描述:

如果你的程序能确定谁是罪犯,则输出他的名字;如果程序判断出不止一个人可能是罪犯,则输出 Cannot Determine;如果程序判断出没有人可能成为罪犯,则输出 Impossible。

示例1

输入

3 1 5
MIKE
CHARLES
KATE
MIKE: I am guilty.
MIKE: Today is Sunday.
CHARLES: MIKE is guilty.
KATE: I am guilty.
KATE: How are you??

输出

MIKE

本题给的规则很详尽但是未知信息太多。谁会是凶手?哪些人说谎?今天周几?由于有未知信息无法推断得到,因为枚举法是这题的基本思想,同时数据规模也给足了枚举的提示。但是,我们还是需要对三个基本问题进行分析,首先,如果我们知道凶手和周几就可以推断出某个人有没有说谎,所以,我们只需要枚举凶手和周几足矣。

思路:枚举凶手、枚举周几,统计可能为凶手的人数,需要判定的信息有两个:

1.对于每个人,要么从头到尾说谎,要么一直都说真话

2.说谎的人数是否足够,注意坑点:有可能有人至始至终没有说过话,设这部分人的数量为other,设我们判断出的说谎者人数为fake,那么应满足fake<=N<=fake+other。(至少fake个人说谎,至多没说话的人也属于说谎者,就是other+fake【当然这个自相矛盾,没说话怎么判定说谎没说谎,问出题人吧->->】)。

代码他来了->->,别问我为什么不优化(数据量太小了,优化效果不明显,而且优化起来代码复杂度简直不忍直视,另外,变量名命名多好,写这种毒瘤题就多轻松):

#include<string>
#include<cstring>
#include<iostream>
using namespace std;

const int N=110;

string weekday[8]={
    "",
    "Today is Monday.",
    "Today is Tuesday.",
    "Today is Wednesday.",
    "Today is Thursday.",
    "Today is Friday.",
    "Today is Saturday.",
    "Today is Sunday."
};
string name[N];
string sentence[N];//存储句子
int state[N],m,n,p,murder_name,murder_count;//state:-1 未说话  0:说真话  1:说假话

int get_person(string Name){ //根据姓名找到索引
    for(int i=1;i<=m;++i){
        if(Name==name[i])return i;
    }
    return -1;
}

int get_state(int murder,int day,int now_person,string now_word){//根据实际凶手 今日周几 当前发言人 当前发言判定当前人有没有说谎
    
  //  cout<<"凶手:"<<name[murder]<<" day:"<<day<<" 发言人:"<<name[now_person]<<" 发言:"<<now_word<<endl;
    
    if(now_word=="I am guilty."){//发言人说自己是罪犯
        if(murder==now_person){//凶手确实是发言人 没有说谎
            return 0;
        }
        return 1;
    }
    
    if(now_word=="I am not guilty."){
        if(murder!=now_person){//凶手确实不是发言人 没有说谎
            return 0;
        }
        return 1;
    }
    
    int t=now_word.find(" is guilty."),word_murder;
    
    if(t!=-1){//当前发言人指认别人是凶手
        word_murder=get_person(now_word.substr(0,t));//难道指认对象的索引
        if(murder==word_murder){//指认正确
            return 0;
        }
        return 1;
    }
    
    t=t=now_word.find(" is not guilty.");
    if(t!=-1){//当前发言人指认别人不是凶手
        word_murder=get_person(now_word.substr(0,t));//难道指认对象的索引
        if(murder!=word_murder){//指认正确
            return 0;
        }
        return 1;
    }
    
    //判断是周几
    for(t=1;t<=7;++t){
        if(weekday[t]==now_word){
            if(t==day){//周几判断正确
                return 0;
            }
            return 1;
        }
    }
    
    return -1;//说了些无关的话,无法判断是否说谎 
}

pair<int,string> deal_sentence(string word){
    int t=word.find(":");
    int person=get_person(word.substr(0,t));
    return make_pair(person,word.substr(t+2));
}

bool check(int murder,int day){//检查这两个条件下 是否可以成立
    memset(state,-1,sizeof(state));
    pair<int,string> murder_word;
    int i,s,now;
    for(i=1;i<=p;++i){//处理每个句子
        
        murder_word=deal_sentence(sentence[i]);
        now=murder_word.first;
        s=get_state(murder,day,now,murder_word.second);
        
        if(s==0){//没有说话
            if(state[now]==1){//之前说过谎
                return false;
            }
            state[now]=0;
        }
        if(s==1){
            if(state[now]==0){
                return false;
            }
            state[now]=1; 
        }
    }
    
    int fake=0,other=0;
    for(i=1;i<=m;++i){
        if(state[i]==1)++fake;
        else if(state[i]==-1)++other;
    }
    return (n>=fake)&&(n<=fake+other);
}

int main(){
    
    int i,j;
    cin>>m>>n>>p;
    
    for(i=1;i<=m;++i)cin>>name[i];

    for(i=0;i<=p;++i)getline(cin,sentence[i]);//用sentence[0]读掉回车
    
    for(i=1;i<=m;++i){  //枚举凶手
        for(j=1;j<=7;++j){ //枚举周几
            if(check(i,j)){//如果i是凶手 今天是周j 能够成立 
                ++murder_count;
                murder_name=i;
                break;
            }
        }
    }
    
    if(!murder_count)cout<<"Impossible";
    else if(murder_count==1)cout<<name[murder_name];
    else cout<<"Cannot Determine";
    
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值