蓝桥杯 疑难杂题题解报告

修改数组

题目大意
给定一个长度为 N N N 的数组 A = [ A 1 , A 2 , ⋅ ⋅ ⋅ A N ] A=[A_1,A_2,⋅⋅⋅A_N] A=[A1,A2,AN],数组中有可能有重复出现的整数。
现在小明要按以下方法将其修改为没有重复整数的数组。
小明会依次修改 A 2 , A 3 , ⋅ ⋅ ⋅ , A N A_2,A_3,⋅⋅⋅,A_N A2,A3,,AN
当修改 A i A_i Ai 时,小明会检查 A i A_i Ai 是否在 A 1 ∼ A i − 1 A_1∼A_{i−1} A1Ai1 中出现过。
如果出现过,则小明会给 A i A_i Ai 加上 1;如果新的 A i A_i Ai 仍在之前出现过,小明会持续给 A i A_i Ai 加 1,直到 A i A_i Ai 没有在 A 1 ∼ A i − 1 A_1∼A_{i−1} A1Ai1 中出现过。
A N A_N AN 也经过上述修改之后,显然 A A A 数组中就没有重复的整数了。
现在给定初始的 A A A 数组,请你计算出最终的 A A A 数组。
输入格式
第一行包含一个整数 N N N
第二行包含 N N N 个整数 A 1 , A 2 , ⋅ ⋅ ⋅ , A N A_1,A_2,⋅⋅⋅,A_N A1,A2,,AN
输出格式
输出 N N N 个整数,依次是最终的 A 1 , A 2 , ⋅ ⋅ ⋅ , A N A_1,A_2,⋅⋅⋅,A_N A1,A2,,AN
数据范围: 1 ≤ N ≤ 1 0 5 , 1 ≤ A i ≤ 1 0 6 1≤N≤10^5,1≤A_i≤10^6 1N105,1Ai106
输入样例

5
2 1 1 3 4

输出样例

2 1 3 4 5

f a [ i ] fa[i] fa[i]表示 i i i 的代表元素
单链表并查集: f a [ i ] fa[i] fa[i]表示链表中的下一个结点。 i i i 所在树的根节点:从 i i i开始往右找第一个没有被用过的位置。

#include <cstdio>
using namespace std;
const int maxn = 1e6 + 7;
int fa[maxn],a[maxn];
void init()  //并查集初始化
{
    for(int i = 1; i < maxn; i++) fa[i] = i;
}
int find(int x)  //路径压缩
{
    if(x != fa[x]) fa[x] = find(fa[x]);
    return fa[x];
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    for(int i = 1; i <= n; i++)
    {
        int x;
        scanf("%d",&x);
        x = find(x);  
        printf("%d ",x); 
        fa[x] = x + 1;
    }
    
    return 0;
}

倍数问题

题目大意
众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。
现在小葱给了你 n n n 个数,希望你从这 n n n 个数中找到三个数,使得这三个数的和是 K K K 的倍数,且这个和最大。
数据保证一定有解。
输入格式
第一行包括 2 个正整数 n ,   K n, K n,K
第二行 n n n 个正整数,代表给定的 n n n 个数。
输出格式
输出一行一个整数代表所求的和。

数据范围: 1 ≤ n ≤ 1 0 5 , 1 ≤ K ≤ 1 0 3 1≤n≤10^5,1≤K≤10^3 1n105,1K103
给定的 n n n 个数均不超过 1 0 8 10^8 108
输入样例

4 3
1 2 3 4

输出样例

9

D p Dp Dp+贪心
f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k]: 表示在 i i i 个数中选 j j j 个数 %K 余数是 k k k
属性:值表示最大值
不选 : f [ i − 1 ] [ j ] [ k ] f[i-1][j][k] f[i1][j][k] 选: f [ i − 1 ] [ j − 1 ] [ ( ( k − x ) f[i-1][j-1][((k-x)%K+K)]+x f[i1][j1][((kx)
f [ i ] [ j ] [ k ] = m a x ( f [ i − 1 ] [ j ] [ k ] , f [ i − 1 ] [ j − 1 ] [ ( ( k − x ) f[i][j][k] = max(f[i-1][j][k],f[i-1][j-1][((k-x)%K+K)]+x) f[i][j][k]=max(f[i1][j][k],f[i1][j1][((kx);
优化:
i i i 层只用了 i − 1 i-1 i1层 且 j j j 严格小于 i i i,并且后面会用到第 i i i 层的数据
然后可以把三维 d p dp dp 优化成一个二维 d p dp dp
将余数相同是值存到同一个数组,然后排序取最值
不断优化取 0 ~ k − 1 k-1 k1 中最大的三个数

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#define pb push_back
using namespace std;
const int maxn = 1e3 + 7;
vector<int>rest[maxn];  //存相同余数
int f[4][maxn];

int main()
{
    int n, K, num;
    scanf("%d%d",&n,&K);
    for(int i = 0; i < n; i++)
    {
        scanf("%d",&num);
        rest[num%K].pb(num);  //余数相同的数存到一起
    }
    memset(f, -0x3f, sizeof f);
    f[0][0] = 0;
    
    for(int i = 0; i < K; i++)
    {
        sort(rest[i].begin(),rest[i].end());  
        reverse(rest[i].begin(),rest[i].end());
        
        for(int j = 0; j < 3 && j < rest[i].size(); j++)  //余数相同取前三大的数
        {
            int x = rest[i][j];
            for(int k = 3; k; k--)
            {
                for(int v = 0; v < K; v++)
                    f[k][v] = max(f[k][v],f[k-1][((v-x)%K+K)%K]+x);
            }
        }
    }
    printf("%d\n",f[3][0]);
    return 0;
}

斐波那契

题目大意
斐波那契数列大家都非常熟悉。它的定义是:
f ( x ) = 1.... ( x = 1 , 2 ) f(x)=1....(x=1,2) f(x)=1....(x=1,2)
f ( x ) = f ( x − 1 ) + f ( x − 2 ) . . . . ( x > 2 ) f(x)=f(x−1)+f(x−2)....(x>2) f(x)=f(x1)+f(x2)....(x>2)
对于给定的整数 n n n m m m,我们希望求出:
f ( 1 ) + f ( 2 ) + … + f ( n ) f(1)+f(2)+…+f(n) f(1)+f(2)++f(n) 的值。
但这个值可能非常大,所以我们把它对 f ( m ) f(m) f(m) 取模。
但这个数字依然很大,所以需要再对 p p p 求模。
输入格式
输入包含多组数据。
每组数据占一行,包含三个整数 n , m , p n,m,p n,m,p
输出格式
每组数据输出一个整数,表示答案。
每个数占一行。
数据范围: 0 < n , m , p < 1 0 18 0<n,m,p<10^{18} 0<n,m,p<1018测试数据不超过100组
输入样例

2 3 5

输出样例

0
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;

ll p;

ll qmul(ll a, ll b)
{
    ll res = 0;
    while (b)
    {
        if (b & 1) res = (res + a) % p;
        a = (a + a) % p;
        b >>= 1;
    }
    return res;
}

void mul(ll c[][2], ll a[][2], ll b[][2])  // c = a * b
{
    static ll t[2][2];
    memset(t, 0, sizeof t);

    for (int i = 0; i < 2; i ++ )
        for (int j = 0; j < 2; j ++ )
            for (int k = 0; k < 2; k ++ )
                t[i][j] = (t[i][j] + qmul(a[i][k], b[k][j])) % p;

    memcpy(c, t, sizeof t);
}

ll F(ll n)
{
    if (!n) return 0;

    ll f[2][2] = {1, 1};
    ll a[2][2] = {
        {0, 1},
        {1, 1},
    };

    for(ll k = n - 1; k; k >>= 1)
    {
        if (k & 1) mul(f, f, a);  // f = f * a
        mul(a, a, a);  // a = a * a
    }

    return f[0][0];
}

ll H(ll m, ll k)  // (F(m - 1) * F(k) - 1) mod F(m)
{
    if (k % 2) return F(m - k) - 1;
    else
    {
        if (k == 0 || m == 2 && m - k == 1) return F(m) - 1;
        else return F(m) - F(m - k) - 1;
    }
}

ll G(ll n, ll m)  // (F(n) - 1) mod F(m)
{
    if (m % 2 == 0)  // m是偶数
    {
        if (n / m % 2 == 0)  // n / m 是偶数
        {
            //cout << n << ' ' << m << ' ' << F(n % m) << endl;
            if (n % m == 0) return F(m) - 1;
            else return F(n % m) - 1;
        }
        else  // n / m 是奇数
        {
            return H(m, n % m);
        }
    }
    else  // m 是奇数
    {
        if (n / m % 2 == 0 && n / 2 / m % 2 == 0)  // n / m 是偶数,n / (2m) 是偶数
        {
            if (n % m == 0) return F(m) - 1;
            else return F(n % m) - 1;
        }
        else if (n / m % 2 == 0 && n / 2 / m % 2)  // n / m 是偶数,n / (2m) 是奇数
        {
            if (m == 2 && n % m == 1) return F(m) - 1;
            else return F(m) - F(n % m) - 1;
        }
        else if (n / m % 2 && n / 2 / m % 2 == 0)  // n / m 是奇数,n / (2m) 是偶数
        {
            return H(m, n % m);
        }
        else  // n / m 是奇数,n / (2m) 是奇数
        {
            if (n % m % 2)
            {
                if (m == 2 && m - n % m == 1) return F(m) - 1;
                else return F(m) - F(m - n % m) - 1;
            }
            else
            {
                return F(m - n % m) - 1;
            }
        }
    }
}

int main()
{
    ll n, m;

    while(~scanf(" %lld%lld%lld",&n,&m,&p))
    {
        ll ans = (G(n + 2, m) % p + p) % p;
        printf("%lld\n",ans);
    }

    return 0;
}

距离

题目大意
给出 n n n 个点的一棵树,多次询问两点之间的最短距离。
注意:
边是无向的。
所有节点的编号是 1 , 2 , … , n 1,2,…,n 1,2,,n
输入格式
第一行为两个整数 n n n m m m n n n 表示点数, m m m 表示询问次数;
下来 n − 1 n−1 n1 行,每行三个整数 x , y , k x,y,k x,y,k,表示点 x x x 和点 y y y 之间存在一条边长度为 k k k
再接下来 m m m 行,每行两个整数 x , y x,y x,y,表示询问点 x x x 到点 y y y 的最短距离。
树中结点编号从 1 到 n n n
输出格式
m m m 行,对于每次询问,输出一行询问结果。
数据范围: 2 ≤ n ≤ 1 0 4 , 1 ≤ m ≤ 2 × 1 0 4 , 2≤n≤10^4,1≤m≤2×10^4, 2n104,1m2×104,
0 < k ≤ 100 , 1 ≤ x , y ≤ n 0<k≤100,1≤x,y≤n 0<k100,1x,yn
输入样例

2 2 
1 2 100 
1 2 
2 1

输出样例

100
100

Tarjan–离线求LCA
在线做法:读一个询问,处理一个,输出一个
离线做法:读完全部询问,再全部处理完,再全部输出

#include <cstdio>
#include <vector>
#include <cstring>
#define PII pair<int,int>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn = 1e4 + 7;
struct node{
    int to, ne;
    ll val;
};
node edge[maxn<<1];
int head[maxn<<1], tot = 0;
int fa[maxn];
int res[maxn<<2];
vector<PII> query[maxn<<1];   //first:存查询另外一个点 second:存查询编号
int dis[maxn<<1];  //存储每个点到根节点的距离
int st[maxn];  //0:未访问  1:正在访问 2:访问并结束回溯
void add(int x, int y, int w)
{
    edge[++tot].to = y;
    edge[tot].val = w;
    edge[tot].ne = head[x];
    head[x] = tot; 
}
void dfs(int now, int ago)
{
    for(int i = head[now]; i; i = edge[i].ne)
    {
        int to = edge[i].to;
        if(to == ago) continue;  //防止回搜
        dis[to] = dis[now] + edge[i].val;
        dfs(to, now);
    }
}
int find(int x)
{
    if(x != fa[x]) fa[x] = find(fa[x]);
    return fa[x];
}
void tarjan(int now)
{
    st[now] = 1;
    for(int i = head[now]; i; i = edge[i].ne)
    {
        int to = edge[i].to;
        if(!st[to])
        {
            tarjan(to);
            fa[to] = now;  //存父节点
        }
    }
    for(auto it : query[now])
    {
        int to = it.first, id = it.second;
        if(st[to] == 2)   //计算 
        {
            int root = find(to);
            res[id] = dis[now] + dis[to] - (dis[root]<<1);
        }
    }
    st[now] = 2;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 1; i < n; i++)
    {
        int x, y; ll w;
        scanf("%d%d%lld",&x,&y,&w);
        add(x, y, w); add(y, x, w);
    }
    for(int i = 1; i <= m; i++)  //查询m次,每次查询的编号
    {
        int x, y;
        scanf("%d%d",&x,&y);
        if(x != y)
        {
            query[x].pb({y, i});
            query[y].pb({x, i});
        }
    }
    
    for(int i = 0; i <= n; i++) fa[i] = i;
    dfs(1,-1);
    tarjan(1);
    for(int i = 1; i <= m; i++) printf("%d\n",res[i]);
    return 0;
}

剪格子

题目大意
如下图所示, 3×3 的格子中填写了一些整数。
在这里插入图片描述
我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是 60。
本题的要求就是请你编程判定:对给定的 m × n m×n m×n 的格子中的整数,是否可以分割为两个连通的部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0。
在这里插入图片描述输入格式
第一行包含两个整数 m , n m,n m,n ,表示表格的宽度和高度。
接下来是 n n n 行,每行 m m m 个正整数,用空格分开。
输出格式
在所有解中,包含左上角的分割区可能包含的最小的格子数目。
如果无法分割,则输出 0。
数据范围: 1 ≤ n , m < 10 , 1≤n,m<10, 1n,m<10,格子内的数均在1到10000之间。
输入样例

3 3
10 1 52
20 30 1
1 2 3

输出样例

3
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <unordered_set>
#define rep(i,a,b) for(auto i = (a); i < (b); i++)
#define per(i,a,b) for(auto i = (a); i > (b); i--)
#define pb push_back
using namespace std;
typedef  unsigned long long ULL;
typedef pair<int,int> PII;
const int maxn = 15, base = 131, inf = 0x3f3f3f3f;

int n, m;
int a[maxn][maxn];
bool st[maxn][maxn];
int sum, res = inf;
PII cands[maxn*maxn];
int fa[maxn*maxn];
unordered_set<ULL> hash_table;

int dir[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1};  //方向
int find(int x)  //路径压缩
{
    if(fa[x] != x) fa[x] = find(fa[x]);
    return fa[x];
}

bool inbound(int x, int l, int r)  //判断位置是否合法
{
    if(x < l || x >= r) return false; //不合法
    return true;
}

bool check_connect(int k)  //检查剩余的是否连通
{
    rep(i, 0, n*m) fa[i] = i;
    int cnt = n*m - k;

    rep(i, 0, n)
        rep(j, 0 , m)
            if(!st[i][j])
            {
                rep(k, 0, 4)
                {
                    int tx = i + dir[k][0], ty = j + dir[k][1];
                    if(!inbound(tx, 0, n) || !inbound(ty, 0, m)) continue;
                    if(st[tx][ty]) continue;

                    int p1 = find(i*m + j),  p2 = find(tx*m + ty);
                    if(p1 != p2)
                    {
                        fa[p1] = p2;
                        cnt--;
                    }
                }
            }
            if(cnt != 1) return false;
            return true;
}

bool check_exists(int k)
{
    static PII bk[maxn*maxn];
    rep(i,0,k) bk[i] = cands[i];
    sort(bk, bk + k);

    ULL x = 0;
    rep(i,0,k)
    {
        x = x*base + bk[i].first + 1;
        x = x*base + bk[i].second + 1;
     }
     if(hash_table.count(x)) return true;
     hash_table.insert(x);
     return false;
}

void dfs(int s, int k)
{
    if(s == sum/2)
    {
        if(check_connect(k)) res = min(res,k);
        return;
    }

    vector<PII> points;
    rep(i, 0, k)
    {
        int x = cands[i].first, y = cands[i].second;
        rep(j, 0 , 4)
        {
            int tx = x + dir[j][0], ty = y + dir[j][1];
            if(!inbound(tx,0,n) || !inbound(ty,0,m)) continue;
            if(st[tx][ty]) continue;

            cands[k] = {tx, ty};
            if(k+ 1 < res && !check_exists(k+1)) points.pb({tx,ty});
        }
    }

    sort(points.begin(), points.end());
    reverse(points.begin(), points.end());
    rep(i, 0, points.size())
    {
        if(!i || points[i] != points[i-1])
        {
            cands[k] = points[i];
            int x = points[i].first, y = points[i].second;
            st[x][y] = true;
            dfs(s + a[x][y], k + 1);
            st[x][y] = false;
        }
    }
}
int main()
{
    scanf("%d%d",&m,&n);
    rep(i, 0, n)
        rep(j, 0, m)
            scanf("%d",&a[i][j]),sum += a[i][j];

    if(sum%2 == 0)
    {
        st[0][0] = true;
        cands[0] = {0, 0};
        dfs(a[0][0], 1);
    }
    if(res == inf) res = 0;
    printf("%d\n",res);
    return 0;
}

组合数问题

题目大意
组合数  C n m C_{n}^{m} Cnm 表示的是从  n n n 个物品中选出  m m m 个物品的方案数。 
举个例子,从 (1, 2, 3) 三个物品中选择两个物品可以有 (1, 2), (1, 3), (2, 3) 这三种选择方法。 
根据组合数的定义,我们可以给出计算组合数  C n m C_{n}^{m} Cnm 的一般公式:
C n m C_n^m Cnm= n ! m ! ( n − m ) ! \frac{n!}{m!(n−m)!} m!(nm)!n!
其中  n !   =   1   ×   2   ×   ⋅   ⋅   ⋅   ×   n n! = 1 × 2 × · · · × n n!=1×2××n。 
小葱想知道如果给定  n n n,  m m m 和  k k k,对于所有的  0   ≤   i   ≤   n 0 ≤ i ≤ n 0in,  0   ≤   j   ≤   m i n ( i ,   m ) 0 ≤ j ≤ min(i, m) 0jmin(i,m) 有多少对  ( i ,   j ) (i, j) (i,j) 满足  C i j C_i^j Cij 是  k k k 的倍数。
输入格式
第一行有两个整数  t ,   k t, k t,k ,其中  t t t 代表该测试点总共有多少组测试数据, k k k 的意义见问题描述。
接下来  t t t 行每行两个整数  n ,   m n, m n,m ,其中  n ,   m n, m n,m 的意义见问题描述。
输出格式
t t t 行,每行一个整数代表所有的  0   ≤   i   ≤   n 0 ≤ i ≤ n 0in,  0   ≤   j   ≤   m i n ( i ,   m ) 0 ≤ j ≤ min(i, m) 0jmin(i,m) 有多少对  ( i ,   j ) (i, j) (i,j) 满足  C i j C_i^j Cij 是  k k k 的倍数。
数据范围: n , m ≤ 2000 , 2 ≤ k ≤ 21 , t ≤ 1 0 4 n,m≤2000,2≤k≤21,t≤10^4 n,m2000,2k21,t104
输入样例

1 2
3 3

输出样例

1

打表求组合数,过百分之90的数据

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2e3 + 7;
ll f[maxn][maxn];
int mod;
void init()
{
    for(int i = 0; i < maxn; i++)
        for(int j = 0; j <= i; j++)
            if(j == 0) f[i][j] = 1;
            else f[i][j] = (f[i-1][j] + f[i-1][j-1])%mod;
}
int main()
{
    int n, m, t;
    scanf("%d%d",&t,&mod);
    init();
    while(t--)
    {
        ll res = 0;
        scanf(" %d%d",&n,&m);
        for(int i = 0; i <= n; i++)
        {
            int t = min(i,m);
            for(int j = 0; j <= t; j++)
                if(f[i][j]%mod == 0) res++;
        }
        printf("%d\n",res);
    }
    return 0;
}

正解打表求组合数+前缀和

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2e3 + 7;
ll f[maxn][maxn], mod;
int s[maxn][maxn];
void init()
{
    for(int i = 0; i < maxn; i++)
        for(int j = 0; j <= i; j++)
        {
            if(j == 0) f[i][j] = 1;
            else f[i][j] = (f[i-1][j] + f[i-1][j-1])%mod;
            
            if(!f[i][j]) s[i][j] = 1;
        }
            
    for(int i = 0; i < maxn; i++)
    {
        for(int j = 0; j < maxn; j++)
        {
            if(i) s[i][j] += s[i-1][j];
            if(j) s[i][j] += s[i][j-1];
            if(i && j) s[i][j] -= s[i-1][j-1];
        }
    }
}
int main()
{
    int n, m, t;
    scanf("%d%d",&t,&mod);
    init();
    while(t--)
    {
        scanf("%d%d",&n,&m);
        printf("%d\n",s[n][m]);
    }
    return 0;
}

模拟散列表

题目大意
维护一个集合,支持如下几种操作:

  1. “ I x ” “I x” Ix,插入一个数 x x x
  2. “ Q x ” “Q x” Qx,询问数 x x x 是否在集合中出现过;
    现在要进行 N N N 次操作,对于每个询问操作输出对应的结果。

输入格式
第一行包含整数 N N N,表示操作数量。
接下来 N N N 行,每行包含一个操作指令,操作指令为 ” I x ” ”I x” Ix ” Q x ” ”Q x” Qx中的一种。
输出格式
对于每个询问指令 “ Q x ” “Q x” Qx,输出一个询问结果,如果 x x x 在集合中出现过,则输出 “ Y e s ” “Yes” Yes,否则输出 “ N o ” “No” No
每个结果占一行。

数据范围: 1 ≤ N ≤ 1 0 5 , − 1 0 9 ≤ x ≤ 1 0 9 1≤N≤10^5,−10^9≤x≤10^9 1N105109x109
输入样例

5
I 1
I 2
I 3
Q 2
Q 5

输出样例

Yes
No

复杂的数据映射到小范围的数
时间复杂度O(n)
1.插入操作
(1)先找到槽
(2)赋值
(3)ne指针指向后面
(4)插入点上一个位置的数的指针指向当前位置

#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e5 + 7;
struct Node{
    int val;  //权值
    int ne;  //指针
};
int tot;
int head[maxn];
Node node[maxn];

int Insert(int x)  //插入
{
   int k = (x%maxn + maxn)%maxn;
   node[++tot].val = x;  //存点
   node[tot].ne = head[k];  //ne指针指向后面
   head[k] = tot; //指向当前位置
}

bool find(int x)  //查询
{
    int k = (x%maxn + maxn)%maxn;
    for(int i = head[k]; i; i = node[i].ne)
        if(node[i].val == x) return true;
    return false;
}

int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        int num;
        char op;
        scanf(" %c%d",&op,&num);
        if(op == 'I') Insert(num);
        else
        {
            if(find(num)) printf("Yes\n");
            else printf("No\n");
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

幸愉聊信奥

谢谢亲的支持,我会继续努力啦~

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

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

打赏作者

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

抵扣说明:

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

余额充值