2021-01-24

by wjl
个人基本是在学习c

2021.1.23

某大学ACM实验室寒假新生培训Day1

day1涉及到高精度和贪心算法
计算机思维如何培养?
计算机思维实际上是一种解决问题的方式,它包括四部分:

  • 分解
  • 模式
  • 抽象
  • 算法
    分解:指将一个复杂的问题拆分成多个简单问题
    比如:99×9=(100-1)×9=900-9=891,就是利用了一种简单的方式解决复杂的算术题,就是分解。
    模式:观察数据的趋势和规律,识别出它是哪一类问题,找出各个部分之间的异同。
    比如:学习认识车辆的时候,会根据是否有四个轮子、是否在马路上跑来判断认识事物。再比如:前面旅游的问题,对于其中的一个小问题路径规划就可以用图论的最短路径理论解决。
    抽象:去掉次要的非本质的部分,抽出共同的本质属性。识别模式形成背后的一般规律。
    抽象的重点在于区分好复杂度,明辨重要和不重要的信息。比如:我们需要画出整个城市的地铁路线图,这时就会忽略不重要的信息,如路线的产短距离,着重突出需要关注的信息,如几号线和每条线之间换乘的站点等。
    算法:未解决某一类问题撰写一系列详细步骤,针对这些类似的问题提供逐步解决的方案
    比如:为了不做无用功,我们需要将之前已经识别处理的问题变成一种通用的模式,找出算法之后,并不等于解决了问题,还需要根据实际问题和场景对算法进行适应性调整——通过优化已有问题的解决方案来针对性提高。

ACM国际大学生程度设计竞赛
竞赛参赛队伍往往由三名在校大学生组成,他们需要在规定的五个小时内解决八个或更多(13个题左右)的复杂实际编程问题,通过比赛能够充分展示大学生创新能力、团队精神和在压力下编写程序、分析和解决问题能力。
19年银川约400支队伍参赛
20年小米线下邀请赛,非出线

年度赛事

  • 国家级
    • ACM国际大学生程序设计竞赛(ICPC)
    • 中国大学生程序设计竞赛(CCPC)
    • 全国高校计算机大赛——团体程序设计天梯赛
  • 省级
    • 河北省ACM大学生程序设计竞赛
    • CCPC(河北赛区)
  • 企业
  • Google Codejam,百度之星,阿里巴巴程序设计大赛,字节跳动……

ACM的益处
学习:玩ACM,C程序设计,数据结构,算法,离散数学等等这些对于大多数同学有难度的课程直接躺过,拿高分也很容易。
工作:据非官方统计,在ACM区域赛上拿到优异成绩的同学,本科毕业数十万年薪不是不可能的,但归根结底还是要自己努力付出,才会有收获。
保研/考研:保研/考研的面试、笔试、上机,对于ACMer来说,小儿科。学好算法,对以后的深造有极大的帮助,研究生导师都很喜欢算法厉害的学生。
交友:玩ACM可以结实各个高校的朋友,精英。
阅历:每年的区域赛都在全国各地举办

问题C:高精度A+B

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
    char a1[100],b1[100];
    int a[100],b[100],c[100],lena,lenb,lenc,i,x;
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    memset(c,0,sizeof(c));
    gets(a1);
    gets(b1);
    lena=strlen(a1);
    lenb=strlen(b1);
    for(i=0;i<=lena-1;i++)
        a[lena-i]=a1[i]-48;
    for(i=0;i<=lenb-1;i++)
        b[lenb-i]=b1[i]-48;
    lenc=1;
    x=0;
    while(lenc<=lena||lenc<=lenb){
        c[lenc]=a[lenc]+b[lenc]+x;
        x=c[lenc]/10;
        c[lenc]%=10;
        lenc++;
    }
    c[lenc]=x;
    if(c[lenc]==0)
        lenc--;
    for(i=lenc;i>=1;i--)
        cout<<c[i];
    cout<<endl;
    return 0;
}

优化后

#include <iostream>
#include <vector>
using namespace std;
typedef vector<int> vint;
vint a, b;
vint add(vint a, vint b){
	vint c;
	int t = 0;
	for (int i = 0; i <= a.size()-1 || i <= b.size()-1; i++){
		if(i <= a.size()-1)t += a[i];
		if(i <= b.size()-1)t += b[i];
		c.push_back(t%10);
		t /= 10;
	}
	if(t)c.push_back(t);
	return c;
}
int main()
{
	string A,B;
	cin >> A >> B;
	for (int i = A.size()-1; i >= 0; i --)a.push_back(A[i]-'0');
	for (int i = B.size()-1; i >= 0; i --)b.push_back(B[i]-'0');
	vint c = add(a, b);
	for (int i = c.size()-1; i >= 0; i --)cout<<c[i];
	return 0;
}

2021.1.24

某大学ACM实验室寒假新生培训Day2

C++常用STL讲解

C++与C语言对比
C语言版本

#include<stdio.h>
int main()
{
    int a,b;
    scanf("%d%d",&a,&b);
    printf("%d",a+b);
    return 0;
}

C++版本

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int a,b;
    cin>>a>>b;
    cout<<a+b;
    return 0;
}

C++也可以兼容C语言

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int a,b;
    scanf("%d%d",&a,&b);
    printf("%d",a+b);
    return 0;
}

C++中的引用
引用是C++新增的内容,就如同C语言的指针一样重要,但它比指针更加方便和易用,有时候甚至是不可或缺的。
同指针一样,引用能够减少数据的拷贝,提高数据的传递效率。

#include<bits/stdc++.h>
using namespace std;
void swap2(int &a,int &b)
{
    int c=a;
    a=b;
    b=c;
}
int main()
{
    int a,b;
    cin>>a>>b;
    swap2(a,b);
    cout<<a<<" "<<b;
    return 0;
}

关于STL(标准模板库)
Standard Template Library,缩写为STL
STL是一个C++软件库,里面包括算法、容器、函数、迭代器。

字符串(string)

string是STL中的一个重要部分,主要用于字符串处理。可以使用输入输出流方式直接进行string读入输出,类似于C语言中的字符数组,由于C++的算法库对string类也有着很好的支持,大多时候字符串处理的问题使用string要比字符数组更加方便。

创建string类型变量

string s;直接创建一个空的(大小为0)的string类型变量s
string s="char";创建string是直接用字符串内容对其赋值,注意字符串要用双引号
string s(int n,char c);创建一个string,由n个c组成,注意c是字符型要用单引号

读入string

cin>>s;durus,遇到空格或回车停止,无论原先s是什么内容都会被新读入的数据替代
getline(cin,s);读入s,空格也会同样读入,直到回车才会停止

输出string

cout<<s;将s全部输出到一行(不带回车)

string中的函数:

赋值运算符:**=将后面的字符串赋值给前面的字符串 o(n)
比较运算符:
== != < <= > >=比较的两个字符串的字典序大小 o(n)
连接运算符:
+ +=**将一个运算符加到另一个运算符后面 o(n)
s[index]返回字符串s中下标为index的字符,string中下标也是从0开始o(1)
s.substr(p,n)返回从s的下标p开始的n个字符组成的字符串,如果n省略就取到底o(n)
s.length()返回字符串的长度o(1)
s.empty()判断s是否为空,空返回1,不空返回0 o(1)
s.erase(p0,len)删除s中从p0开始的len个字符,如果len省略就删到底 o(n)
s.erase(s.begin()+i)删除下标为i个字符 o(n)
s1.insert(p0,s2,pos,len)后面两个参数截取s2,可以省略 o(n)
s.insert(p0,n,c)在p0处插入n个字符c o(n)
s.replace(p0,len0,s2,pos,len)删除p0开始的len0个字符,然后在p0处插入字符串s2中从pos开始的len个字符,后两个参数可以省略 o(n)
s1.find(s2,pos)从前往后,查找成功时返回第一次出现的下标,失败时返回string::npos的值(-1) 0(n×m)
s1.rfind(s2,pos)从pos开始从后往前查找字符串s2中字符串后边第一次出现的下标0 (n×m)

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s(3,'6'),ss;
    ss=s;
    s=s+ss;
    cout<<s<<' '<<ss;
    return 0;
}

string相关函数

例题:6翻了

一、描述
“666”是一种网络用语,大概是表示某人很厉害、我们很佩服的意思。最近又衍生出另一个数字“9”,意思是“6翻了”,实在太厉害的意思。如果你以为这就是厉害的最高境界,那就错啦 —— 目前的最高境界是数字“27”,因为这是 3 个 “9”!

本题就请你编写程序,将那些过时的、只会用一连串“6666……6”表达仰慕的句子,翻译成最新的高级表达。

二、输入格式
输入在一行中给出一句话,即一个非空字符串,由不超过 1000 个英文字母、数字和空格组成,以回车结束。

三、输出格式
从左到右扫描输入的句子:如果句子中有超过 3 个连续的 6,则将这串连续的 6 替换成 9;但如果有超过 9 个连续的 6,则将这串连续的 6 替换成 27。其他内容不受影响,原样输出。

四、输入样例
it is so 666 really 6666 what else can I say 6666666666
1
五、输出样例
it is so 666 really 9 what else can I say 27

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string str;
    getline(cin,str);
    for(int i=0;i<str.length();i++)
    {
        if(str[i]=='6')
        {
            int j=1;//j代表连续6的个数
            while(i+j<str.lengeh()&&str[i+j]=='6')j++;
            if(j>9)str.replace(i,j,"27");
            else if(j>3)str.replace(i,j,"9");
        }
    }
    cout<<str<<endl;
}
vector

vector容器是STL中最常用的容器之一,它和array容器非常类似,都可以看做是对C++普通数组的“升级版”。不同之处在于,array实现的是静态数组(容量固定的数组),而vector实现的是一个动态数组,即可以进行元素的插入和删除,在此过程中,vector会动态调整所占用的内存空间,整个过程无需人工干预。
C++ vector容器
vectorv 创建动态数组v,后面可以加{}或()进行初始化
type v[index]获取v中第 index 个元素 O(1)
v.push_back(type item)向v后⾯添加⼀个元素item O(1) (item的类型要和v是相同类型)
v.pop_back()删除 v 最后⼀个元素 O(1)
v.size()获取 v 中元素个数,返回size_type类型 O(1)
v.resize(int n)把 v 的⻓度设定为 n 个元素 O(n)
v.empty()判断 v 是否为空,空返回1,不空返回0,O(1)
v.clear()清空 v 中的元素 O(size)
v.insert(iterator it,type x)向迭代器it指向元素前增加一个元素x,O(n)
v.erase(iterator it)删除向量中迭代器指向元素,O(n)
v.front()返回首元素的引用O(1)
v.back()返回尾元素的引用O(1)
v.begin()返回首迭代器,指向第一个元素O(1)
v.end()返回尾迭代器,指向向量最后一个元素的下一个位置O(1)

vector的创建
#include <bits/stdc++.h>
using namespace std;
int main()
{
    vector<int>v1;
    //创建一个存int类型的动态数组,int可以改成其它类型
    vector<double>v2{1,1,2,3,5,8};
    //创建一个存double类型的动态数组,长度为6,1 1 2 3 5 8分别存在v[0]~v[5]
    vector<long long>v3(20);
    //创建一个存long long类型的动态数组,长度为20,v[0]~v[19]默认为0
    vector<string>v4(20,"mdltxdy");
    //创建一个存string类型的动态数组,长度为20,存的都是"zzuacm"
    vector<int>v5[3];
    //相当于存int的二维数组,一共3行,每行的列可变
    vector<vector<int> >v5{{1,2},{1},{1,2,3}};
    //存int的二维数组,行和列都可变,初始状态
    return 0;
}
vector基本操作函数
int main()
{
    vector<int>v;
    for(int i=1;i<=5;i++)
        v.push_back(i);//向动态数组中插入1~5
    cout<<v.size()<<endl;//输出数组的大小,有几个值
    for(int i=0;i<5;i++)
        cout<<v[i]<<" ";//输出v[0]~v[4],也就是1~5
    cout<<endl;
    v.clear();//将v清空,此时size为0
    v.resize(10);//为v重新开辟大小为10的空间,初始为0
    for(int i=0;i<v.size();i++)
        cout<<v[i]<<" ";//遍历每一个元素
    while(!v.empty())//当v还不空的话,去掉v的最后一个元素,等同于v.clear();
        v.pop_back();
    return 0;
}
vector插入、删除、遍历
int main()
{
    vector<int>v{0,1,2,3,4};
    v.erase(v.begin()+3);//删除v[3],v变为{0,1,2,4}
    v.insert(v.begin()+3,666);//在v[3]前加上666,v变成{0,1,2,666,4}
    v.front()=10;//将v[0]改成10,等同于v[0]=10;
    v.back()=20;//将v[4]改成20等同于v[v.size()-1]=20;
    for(int i=0;i<v.size();i++)
        cout<<v[i]<<" ";//使用下标访问的方法遍历v
    cout<<endl;
    for(auto i=v.begin();i!=v.end();i++)
        cout<<*i<<" ";//使用迭代器,从v.begin()到v.end()-1
    cout<<endl;
    for(auto i:v)//使用C++新特性循环遍历v,如果需要改变i的值,还需要在前面加上&
        cout<<i<<" ";
    cout<<endl;
    return 0;
}

关于迭代器(iterator)
vector<int>::iterator it=v.begin();
auto it=v.begin();
两者等价
在这⾥ it 类似于⼀个指针,指向 v 的第⼀个元素
it 等价于 &v[0]
*it等价于 v[0]
it 也可以进⾏加减操作,例如 it + 3 指向第四个元素
it++ 后it指向的就是v的第二个元素(v[1])了

队列(queue)

queue只能在容器的末尾添加新元素,只能从头部移除元素。
C++ STL–queue的使用方法

创建方法

queue<type>q;建立一个存放数据类型为type的队列q

使用方法

q.push(item);在 q 的最后添加⼀个type类型元素item O(1)
q.pop();使 q 最前⾯的元素出队 O(1)
q.front();获取 q 最前⾯的元素 O(1)
q.size();获取 q 中元素个数 O(1)
q.empty();判断 q 是否为空,空返回1,不空返回0 O(1)

优先队列(priority_queue)

priority_queue中出队顺序与插⼊顺序⽆关,与数据优先级有关,本质是一个堆
priority_queue的用法

创建方法
priority_queue<Type, Container, Functional>
// Type:数据类型
// Container:存放数据的容器,默认⽤的是 vector
// Functional:元素之间的⽐较⽅法,当type可以比较时后两个可以省略
使用方法

pq.push(item);在 pq 中添加⼀个元素 O(logn)
pq.top();获取 pq 最大的元素 O(1)
pq.pop();使 pq 中最大的元素出队 O(logn)
pq.size();获取 pq 中元素个数 O(1)
pq.empty();判断 pq 是否为空 O(1)

样例

#include <bits/stdc++.h>
using namespace std;
int main()
{
    priority_queue<int> pq;
//    priority_queue<int,vector<int>,greater<int> >pq;
    pq.push(1);
    pq.push(3);
    pq.push(2);
    while (!pq.empty())
    {
        cout << pq.top() << endl;
        pq.pop();
    }
    return 0;
}

priority_queue中存的元素如果是结构体这样无法进行比较的类型,必须要重载运算符<,相当于先使得优先队列中的元素可以进行比较再建立pq,否则直接建优先队列是会报错的.

#include <bits/stdc++.h>
using namespace std;
struct Node{
    int x,y;
};
bool operator<(Node a,Node b){
    return a.x<b.x;
}
int main(){
    priority_queue<Node> pq;
    pq.push({1,3});
    pq.push({3,2});
    pq.push({2,1});
    while(!pq.empty())
    {
        cout<<pq.top().x<<' '<<pq.top().y<<endl;
        pq.pop();
    }
    return 0;
}
例题:洛谷p3378【模板】堆

例题

#include<bits/stdc++.h>
using namespace std;
int main(){
    priority_queue<int, vector<int>, greater<int> > pq;
    int n, x, y;
    cin>>n;
    while(n--){
        cin>>x;
        if(x==1){
            cin>>y;
            pq.push(y);
        }else if(x==2){
            cout<<pq.top()<<endl;
        }else{
            pq.pop();
        }
    }
    return 0;
}
集合(set)

集合(set)是一种包含对象的容器,可以快速地(logn)查询元素是否在已知几集合中。
set 中所有元素是有序地,且只能出现⼀次,因为 set 中元素是有序的,所以存储的元素必须已经定义 过「<」运算符(因此如果想在 set 中存放 struct 的话必须⼿动重载「<」运算符,和优先队列一样)

与set类似的还有
multiset元素有序可以出现多次
unordered_set元素无序只能出现一次
unordered_multiset元素无序可以出现多次
set–常见成员函数及基本用法

建立方法
set<Type>s;
multiset<Type>s;
unorded_set<Type>s;
unorded_multiset<Type>s;

如果Type无法进行比较,还需要和优先队列一样定义<运算符

遍历方法
for(auto i:s)cout<<i<<" ";
//和vector的类似
使用方法

s.insert(item);在 s 中插⼊⼀个元素 O(logn)
s.size();获取 s 中元素个数 O(1)
s.empty();判断 s 是否为空 O(1)
s.clear();清空 s O(n)
s.find(item);在 s 中查找⼀个元素并返回其迭代器,找不到的话返回 s.end() O(logn)
s.begin();返回 s 中最小元素的迭代器,注意set中的迭代器和vector中的迭代器不同,无法直接加上某个数,因此要经常用到–和++O(1)
s.end();返回 s 中最大元素的迭代器的后一个迭代器 O(1)
s.count(item);返回 s 中 item 的数量。在set中因为所有元素只能在 s 中出现⼀次,所以返回值只能是 0 或 1,在multiset中会返回存的个数 O(logn)
s.erase(position);删除 s 中迭代器position对应位置的元素O(logn)
s.erase(item);删除 s 中对应元素 O(logn)
s.erase(pos1, pos2);删除 [pos1, pos2) 这个区间的位置的元素 O(logn + pos2 - pos1)
s.lower_bound(item);返回 s 中第一个大于等于item的元素的迭代器,找不到就返回s.end() O(logn)
s.upper_bound(item);返回 s 中第一个大于item的元素的迭代器,找不到就返回s.end() O(logn)

映射(map)

map 是照特定顺序存储由 key 和 value 的组合形成的元素的容器, map 中元素按照 key 进⾏排序,每个 key 都是唯⼀的,并对应着一个value,value可以重复
map的底层实现原理与set一样都是红黑树

与map类似的还有unordered_map,区别在于key不是按照顺序排序
C++中map的用法详解
例题

建立方法
map<key, value> mp;
unordered_map<key, value>mp;
遍历方法
for(auto i:mp)
    cout<<i.first<<' '<<i.second<<endl;
map的常用函数

mp.size();获取 mp 中元素个数 O(1)
mp.empty();判断 mp 是否为空 O(1)
mp.clear();清空 mp O(1)
mp.begin();返回 mp 中最小 key 的迭代器,和set一样,只可以用到–和++操作 O(1)
mp.end();返回 mp 中最大 key 的迭代器的后一个迭代器 O(1)
mp.find(key);在 mp 中查找⼀个 key 并返回其 iterator,找不到的话返回 s.end() O(logn)
mp.count(key);在 mp 中查找 key 的数量,因为 map中 key 唯⼀,所以只会返回 0 或 1 O(logn)
mp.erase(key);在 mp 中删除 key 所在的项,key和value都会被删除 O(logn)
mp.lower_bound(item);返回 mp 中第一个key大于等于item的迭代器,找不到就返回mp.end() O(logn)
mp.upper_bound(item);返回 mp 中第一个key大于item的迭代器,找不到就返回mp.end() O(logn)
mp[key];返回 mp 中 key 对应的 value。如果key 不存在,则返回 value 类型的默认构造器(defaultconstructor)所构造的值,并该键值对插⼊到 mp 中O(logn)
mp[key] = xxx;如果 mp 中找不到对应的 key 则将键值对 (key: xxx) 插⼊到 mp 中,如果存在 key 则将这个 key 对应的值改变为 xxx O(logn)

unordered的作用

set和map都可以在前面加上unorder使得内部的元素改成不按顺序存储的,其余的功能都不改变,虽然无法顺序存储,但底层原理是hash,可以使得所有的查询、修改、删除操作都变成O(1)复杂度

二进制有序集(bitset)

bitset是一种类似数组的结构,它的每一个元素只能是0或1,每个元素仅用1bit空间。
C++的bitset

建立方法
bitset<n>b;//建立一个可以存n位二进制的有序集
bitset<n>b(unsigned long u);//坐标从后往前计数,高位在前
bitset<n>b(string s);//将由'0'和'1'组成的字符串赋值给
支持所有位操作:| |= & &= << <<= >> >>=
cout<<b;//bitset可以直接用cout输出
b[index];//可以用下标操作符来读或写某个索引位置的二进制位
//比如bitset<10>b(5);等价于bitset<10>b("1010");
//其中cout<<b输出0000001010
//for(int i=0;i<10;i++)cout<<b[i];输出0101000000
使用方法

b.count();count函数用来求bitset中1的位数
b.size();size函数用来求bitset的大小
b.any();any函数检查bitset中是否有1
b.none();none函数检查bitset中是否没有1
b.all();all函数检查bitset中是全部为1
foo.flip();flip函数不指定参数时,将bitset每一位全部取反
foo.set();set函数不指定参数时,将bitset的每一位全部置为1
foo.reset();reset函数不传参数时将bitset的每一位全部置为0
string s = foo.to_string();将bitset转换成string类型
unsigned long a = foo.to_ulong();将bitset转换成unsigned long类型
unsigned long long b = foo.to_ullong();将bitset转换成unsigned long long类型

常用函数

max(val1, val2);返回更⼤的数
min(val1, val2);返回更⼩的数
swap(type, type);交换两者的值,可以是两个值也可以是两个STL的容器

排序函数(sort)
sort(first, last, compare)

first:排序起始位置(指针或 iterator)
last:排序终⽌位置(指针或 iterator)
compare:⽐较⽅式,可以省略,省略时默认按升序排序,如果排序的元素没有定义比较运算(如结构体),必须有compare
sort 排序的范围是 [first, last),时间为 O(nlogn)

样例

#include<bits/stdc++.h>
using namespace std;
bool cmp(int a,int b){return a>b;}
int main()
{
    int arr[]={3,2,5,1,4};
    sort(arr,arr+5);
    sort(arr,arr+5,greater<int>());
    sort(arr,arr+5,cmp);
    sort(arr,arr+5,[](int a,int b){return a>b;});
    return 0;
}
例题

点赞狂魔

去重函数(unique)
unique(first, last);

[first, last)范围内的值必须是一开始就提前排好序的
移除 [first, last) 内连续重复项
去重之后的返回最后一个元素的下一个地址(迭代器)

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int arr[]={3,2,2,1,2},n;
    sort(arr,arr+5);//需要先排序
    n=unique(arr,arr+5)-arr;//n是去重后的元素个数
    return 0;
}
二分函数(lower_bound/upper_bound)
lower_bound(first, last, value)

first:查找起始位置(指针或 iterator)
last:查找终⽌位置(指针或 iterator)
value:查找的值
lower_bound 查找的范围是 [first, last),返回的是序列中第⼀个大于等于 value 的元素的位置,时间为 O(logn)
[first, last)范围内的序列必须是提前排好序的,不然会错
如果序列内所有元素都⽐ value ⼩,则返回last·upper_bound(first, last, value)
upper_bound 与 lower_bound 相似,唯⼀不同的地⽅在于upper_bound 查找的是序列中第⼀个⼤于 value 的元素

int main()
{
    int arr[]={3,2,5,1,4};
    sort(arr,arr+5);//需要先排序
    cout << *lower_bound(arr,arr+5,3);//输出数组中第一个大于等于3的值
    return 0;
}
next_permutation
next_permutation(first, last)

用于求序列[first,last)元素全排列中一个排序的下一个排序

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int a[3] = {0, 1, 2};
    do
    {
        for (int i = 0; i < 3; i++)
            cout<<a[i]<<' ';
        cout<<endl;
    }
    while (next_permutation(a, a + 3));
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值