《数据结构》专题3--串和数组

A - 数据结构实验之串一:KMP简单应用

Description

给定两个字符串string1和string2,判断string2是否为string1的子串。

Input

 输入包含多组数据,每组测试数据包含两行,第一行代表string1(长度小于1000000),第二行代表string2(长度小于1000000),string1和string2中保证不出现空格。

Output

 对于每组输入数据,若string2是string1的子串,则输出string2在string1中的位置,若不是,输出-1。

Sample

Input 

abc
a
123456
45
abc
ddd

Output 

1
4
-1

Hint

#include<bits/stdc++.h>
using namespace std;

const int N = 1e6 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
string s1, s2;
int Next[N];
// i一直向前,j会回溯
// 这只是匹配之前对模式串的预处理而已
void getnext(){// Next[]数组只与s2(模式串)有关
    int n = s2.size();
    int j = 0, k = -1;
    Next[0] = -1;// 格外重要!
    while(j < n){
        if(k == -1 || s2[j] == s2[k]){
            j++;
            k++;
            Next[j] = k;
            // 上面3行可以用这一行代替:Next[++j] = ++k;
        }
        else  k = Next[k];// hin难理解的地方www
    }
}
int kmp(){
    int len1 = s1.size();
    int len2 = s2.size();
    int i = 0, j = 0;// i指向主串,j指向模式串
    while(i < len1 && j < len2){
        if(j == -1 || s1[i] == s2[j]){
            i++;j++;
        }
        else j = Next[j];// 当j=0时Next[j]就会等于-1
    }
    if(j == len2) return i - j + 1;
    // 我认为对于return i-j+1 可以这样理解:
    //1234123412345 i=13
    //        12345 j=5
    else return -1;
}
int main()
{
    while(cin >> s1 >> s2){
        getnext();
        int f = kmp();
        cout << f << endl;
    }
    return 0;
}

**关于kmp:可以看这篇文章理解:kmp算法(最简单最直观的理解,看完包会)_u014390156的博客-CSDN博客_kmp算法的简单理解然后学习代码的实现:KMP算法—终于全部弄懂了_dark_cy的博客-CSDN博客_kmp算法 

最后如果想更深入的理解、拓展:从头到尾彻底理解KMP(2014年8月22日版)_结构之法 算法之道-CSDN博客_kmp  

关于求解next数组:串′ababaaababaa′的next数组(求next数组思路与实例)_疯狂的1024-CSDN博客_串ababaaababaa的next数组为 

**// 我认为对于return i-j+1; 可以这样理解:
    //1234123412345 i=13
    //                12345 j=5 

**kmp比较难理解,建议常温习以加深理解。 

B - 数据结构实验之串二:字符串匹配

Description

  给定两个字符串string1和string2,判断string2是否为string1的子串。

Input

 输入包含多组数据,每组测试数据包含两行,第一行代表string1,第二行代表string2,string1和string2中保证不出现空格。(string1和string2大小不超过100字符)

Output

 对于每组输入数据,若string2是string1的子串,则输出"YES",否则输出"NO"。

Sample

Input 

abc
a
123456
45
abc
ddd

Output 

YES
YES
NO

Hint

#include<bits/stdc++.h>
using namespace std;

const int N = 1e6 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
string s1, s2;
int Next[N];
// i一直向前,j会回溯
// 这只是匹配之前对模式串的预处理而已
void getnext(){// Next[]数组只与s2(模式串)有关
    int n = s2.size();
    int j = 0, k = -1;
    Next[0] = -1;// 格外重要!
    while(j < n){
        if(k == -1 || s2[j] == s2[k]){
            j++;
            k++;
            Next[j] = k;
            // 上面3行可以用这一行代替:Next[++j] = ++k;
        }
        else  k = Next[k];// hin难理解的地方www
    }
}
int kmp(){
    int len1 = s1.size();
    int len2 = s2.size();
    int i = 0, j = 0;// i指向主串,j指向模式串
    while(i < len1 && j < len2){
        if(j == -1 || s1[i] == s2[j]){
            i++;j++;
        }
        else j = Next[j];// 当j=0时Next[j]就会等于-1
    }
    if(j == len2) return i - j + 1;
    else return -1;
}
int main()
{
    while(cin >> s1 >> s2){
        getnext();
        int f = kmp();
        if(f == -1) cout << "NO" << endl;
        else cout << "YES" << endl;
    }
    return 0;
}

C - 数据结构实验之串三:KMP应用

Description

有n个小朋友,每个小朋友手里有一些糖块,现在这些小朋友排成一排,编号是由1到n。现在给出m个数,能不能唯一的确定一对值l和r(l <= r),使得这m个数刚好是第l个小朋友到第r个小朋友手里的糖块数?

Input

首先输入一个整数n,代表有n个小朋友。下一行输入n个数,分别代表每个小朋友手里糖的数量。

之后再输入一个整数m,代表下面有m个数。下一行输入这m个数。

Output

 如果能唯一的确定一对l,r的值,那么输出这两个值,否则输出-1

Sample

Input 

5
1 2 3 4 5
3
2 3 4

Output 

2 4
#include<bits/stdc++.h>
using namespace std;

const int N = 1e6 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
char s1[N], s2[N];
int Next[N];
void getnext(){
    int n = strlen(s2);
    int j = 0, k = -1;
    Next[0] = -1;
    while(j < n){
        if(k == -1 || s2[j] == s2[k]){
            Next[++j] = ++k;
        }
        else k = Next[k];
    }
}
int kmp(char s1[], char s2[]){// 因为要二次判断,所以这里有一点点改变
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int i = 0, j = 0;
    while(i < len1 && j < len2){
        if(j == -1 || s1[i] == s2[j]){
            i++;j++;
        }
        else j = Next[j];
    }
    if(j == len2) return i - j + 1;
    else return -1;
}
int main()
{
    int n, m;
    cin >> n;
    for(int i = 0; i < n; i++) cin >> s1[i];
    cin >> m;
    for(int i = 0; i < m; i++) cin >> s2[i];
    getnext();
    int f = kmp(s1, s2);
    if(f != -1){
        if(kmp(s1+f, s2) != -1){
            cout << "-1";
        }
        else cout << f << " " << f + m - 1;
    }
    else cout << "-1";
    return 0;
}

D - 串结构练习——字符串连接

Description

 给定两个字符串string1和string2,将字符串string2连接在string1的后面,并将连接后的字符串输出。

连接后字符串长度不超过110。 

Input

 输入包含多组数据,每组测试数据包含两行,第一行代表string1,第二行代表string2。

Output

 对于每组输入数据,对应输出连接后的字符串,每组输出占一行。

Sample

Input 

123
654
abs
sfg

Output 

123654
abssfg

Hint

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
string s1, s2;
int main()
{
    while(cin >> s1 >> s2){
        s1 += s2;
        cout << s1 << endl;
    }
    return 0;
}

E - 学密码学一定得学程序

Description

曾经,ZYJ同学非常喜欢密码学。有一天,他发现了一个很长很长的字符串S1。他很好奇那代表着什么,于是神奇的WL给了他另一个字符串S2。但是很不幸的是,WL忘记跟他说是什么意思了。这个时候,ZYJ不得不求助与伟大的ZP。ZP笑了笑说,这个很神奇的,WL的意思是只要你找到她给你的字符串在那个神奇的字符串的位置,你就会有神奇的发现。ZYJ恍然大悟,原来如此,但是悲剧来了,他竟然不知道怎么找。。。。是的,很囧是不是。所以这时候就需要化身为超级玛丽亚的你现身了,告诉他吧。。。。。。

Input

首先输入一个n。表示有n组测试数据。

每组测试数据有两行。

第一行为字符串S1,长度不大于1000000。

第二行为字符串S2,长度不大于10000,并且长度不小于2。

Output

输出S2在S1的位置。如果有多个位置,只输出第一个位置。

如果找不到,就输出“::>_<::“(不输出双引号)。

Sample

Input 

1
ASDFGDF
DF

Output 

3

Hint

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
string s1, s2;
int Next[N];
void getnext(){
    int n = s2.size();
    int j = 0, k = -1;
    Next[0] = -1;
    while(j < n){
        if(k == -1 || s2[j] == s2[k]){
            Next[++j] = ++k;
        }
        else k = Next[k];
    }
}
int kmp(){
    int len1 = s1.size();
    int len2 = s2.size();
    int i = 0, j = -1;
    while(i < len1 && j < len2){
        if(j == -1 || s1[i] == s2[j]){
            i++;j++;
        }
        else j = Next[j];
    }
    if(j == len2) return i - j + 1;
    else return -1;
}
int main()
{
    int n;
    cin >> n;
    while(n--){
        cin >> s1 >> s2;
        getnext();
        int f = kmp();
        if(f == -1) cout << "::>_<::" << endl;
        else cout << f << endl;
    }
    return 0;
}

F - 又见回文

Description

    “回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。现在呢,就是让你判断输入的字符串是否是回文串。

Input

    有多组输入,每行输入一串字符,保证字符串长度不会大于 100000,字符串由大小写英文字母和空格组成,以字符串“2013”作为结束标志。

Output

    每行输出一个字符串,如果输入是回文串,输出“YES”,否则输出“NO”(注意:判断的时候空格是不作判断的,详见样例)。

Sample

Input 

aaaa
ggg g
lozxvxoMJBCHsTXooXTsHCBJMoxvxzol
i am a good acmer
2013

Output 

YES
YES
YES
NO

Hint

 
#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;

int main()
{
    string s1, s2;
    while(getline(cin, s1)){
        if(s1 == "2013") break;
        else{
            s2 = "";// 初始化为空
            int n = s1.size();
            for(int i = 0; i < n; i++){
                if(s1[i] != ' ')  s2 += s1[i];
            }
            s1 = s2;
            reverse(s2.begin(), s2.end());
            if(s1 == s2) cout << "YES" << endl;
            else cout << "NO" << endl;
        }
    }
    return 0;
}

G - 字符串扩展

Description

Tom有些时候为了记录的方便,常常将一些连续的字符用扩展符'-'简单表示。比如abcdefg可以简写为a-g,即用起始的字符和终止字符中间加上一个扩展符'-'来表示这个字符串。但是为了处理的方便,Tom又必须将这些我们简单记法扩展成原来的字符串。很明显要是人工来做的话必定很麻烦,Tom知道计算机可以帮助他完成这个任务,但是他却不会编程,这的确让他很上火。他知道今天是山东理工大学第三届ACM校赛的日子,届时来自全校的编程爱好者都会来参加比赛,他很兴奋,因为这个困惑他良久的问题终于要被解决了。给你一个含有扩展符'-'的字符串,你的任务就是将他还原成原来的字符串。要求是只处理[a-z]、[A-Z]、[0-9]范围内的字符扩展,即只有当扩展符前后的字符同时是小写字母、大写字母或数字时并且扩展符前面的字符不大于后面的字符才进行扩展,其它情况不进行扩展,原样输出。例如:a-R、D-e、0-b、4-B等字符串都不进行扩展。

Input

第一行是一个正整数T,表示共有T组测试数据(T < 100)。下面的T行,每一行包括一个长度不大于1000的待扩展字符串.

Output

每组测试数据输出一行扩展后的字符串。

Sample

Input 

3
ADEa-g-m02
acm-0-5-a-ac-cm-m-A-AC-CM-M
Welcometothe3rdACM/ICPCCampusProgrammingContestofSDUT-1-3-A-z-a-Z

Output 

ADEabcdefghijklm02
acm-012345-aaccmm-AACCMM
Welcometothe3rdACM/ICPCCampusProgrammingContestofSDUT-123-A-z-a-Z

Hint

#include<bits/stdc++.h>
using namespace std;

const int N = 1e3 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
char a[N];
int main()
{
    int t;
    cin >> t;
    while(t--){
        scanf("%s", a);
        int n = strlen(a);
        for(int i = 0; i < n; i++){
            if(a[i]=='-'&&a[i-1]<a[i+1]&&a[i-1]>='a'&&a[i-1]<='z'&&a[i+1]<='z'&&a[i+1]>='a'){
                for(char j = a[i-1]+1; j < a[i+1]; j++) printf("%c", j);// 这里只输出需要扩展的那些就行
            }
            else if(a[i]=='-'&&a[i-1]<a[i+1]&&a[i-1]>='A'&&a[i-1]<='Z'&&a[i+1]<='Z'&&a[i+1]>='A'){
                for(char j = a[i-1]+1; j < a[i+1]; j++) printf("%c", j);
            }
            else if(a[i]=='-'&&a[i-1]<a[i+1]&&a[i-1]>='0'&&a[i-1]<='9'&&a[i+1]<='9'&&a[i+1]>='0'){
                for(char j = a[i-1]+1; j < a[i+1]; j++) printf("%c", j);
            }
            else printf("%c", a[i]);// 这里会把头尾字符输出
        }
        printf("\n");
    }
    return 0;
}

H - cyk追楠神系列一

Description

众所周知,cyk 是个奇特的人,有一天,他终于又做出了一个惊 (zheng) 人 (chang) 的决定,他决定追楠神了!于是 cyk 就写了一封信向楠神表白。但是楠神作为 acm 的大佬,怎么能轻易答应 cyk,他决定对信做一个考察,为此他特意定义了“爱的证据”,“爱的证据”即如果在信里的一个长度等于 k 的字符子串里包含“love”,那么这就是一个“爱的证据”,比如 k=5 时,字符串“i love you”里“ love”和“love ”就是“爱的证据”。 现在,楠神想知道 cyk 写的信里有多少个“爱的证据”,假如“爱的证据”超过 m,那么他就会答应 cyk,如果小于等于 m,那么他就会丑拒。由于 cyk 的字太丑,所以楠神就把这项任务交给了你。

Input

第一行输入 t (1 <= t <= 100),代表有 t 组输入数据。

每组数据第一行输入 m, k (1 <= m, k <= 10^3)。

第二行输出一个字符串 a,长度不超过 10^3。

Output

每组输出占一行,假如楠神可以答应 cyk,就输出“congratulation”,如果不能就输出“too ugly to accept”。

Sample

Input 

1
1 5
i love you

Output 

congratulation
#include<bits/stdc++.h>
using namespace std;
 
const int N = 1e3 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
string s;
int main()
{
    int t;
    cin >> t;
    while(t--){
        int cnt = 0;
        int m, k;
        cin >> m >> k;
        getchar();
        getline(cin, s);
        //if(k < 4) cnt = 0;
        //else{
            int n = s.size();
            for(int i = 0; i < n - k + 1; i++){
                for(int j = i; j <= i + k - 4; j++){
                    if(s[j] == 'l' && s[j+1] == 'o' && s[j+2] == 'v' && s[j+3] == 'e'){
                        cnt++;
                        break;
                    }
                }
            }
            if(m < cnt) printf("congratulation\n");
            else printf("too ugly to accept\n");
        //}
        
    }
    return 0;
}

**

I - bLue的文件查找器

Description

bLue 的电脑里存了各种各样的文件,随着文件越来越多,查找文件也成了一个麻烦事。

现在,他想要查找所有指定格式(扩展名)的文件,不过他并不会使用文件管理器自带的搜索功能,所以他想求你写一个文件查找器,来帮他查找所有指定格式的文件。

Input

输入数据有多组(数据组数不超过 100),到 EOF 结束。

对于每组数据:

  • 第一行输入一个整数 n (1 <= n <= 100) 和一个长度不超过 5 的字符串 ex,分别表示文件夹内的文件数量和要查找的文件的扩展名。
  • 接下来的 n 行,每行输入一个完整文件名。保证文件名不包含空格且长度不超过 100。

Output

对于每组数据,按照输入顺序输出文件夹内所有扩展名符合查找要求的文件名。

Sample

Input 

6 cpp
3717.cpp
xunhuansai_daima.zip
xunhuansai_jietibaogao.pdf
C.cpp
bLue.jpg
cyk_de_richang.mp4

Output 

3717.cpp
C.cpp
#include<bits/stdc++.h>
using namespace std;

const int N = 1e2 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
string s, t, a;
int main()
{
    int n;
    while(~scanf("%d", &n)){
        cin >> a;
        while(n--){
            getchar();
            t = "";
            cin >> s;
            int len = s.size();
            for(int i = len - 1; i >= 0; i--){
                if(s[i] == '.') break;
                t += s[i];
            }
            reverse(t.begin(), t.end()); 
            if(t == a) cout << s << endl;
        }
    }
    return 0;
}

**i = len - 1   记住!! !一定要记住(T_T)

**mark

J - Power Strings

Description

Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n).

Input

 Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.

Output

 For each s you should print the largest n such that s = a^n for some string a.

Sample

Input 

abcd
aaaa
ababab
.

Output 

1
4
3

Hint

 This problem has huge input, use scanf instead of cin to avoid time limit exceed.

#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

typedef long long LL;
const int N = 1e6 + 100;
const int M = 2e2 + 100;
const int MAXN = 0x3f3f3f3f;
const LL LMANX = 0x3f3f3f3f3f3f3f3f;
#define PI 3.14159265358979323846
char s[N];
int Next[N];
void Get_Next(char *s){
    int n = strlen(s);
    int j = 0, k = -1;
    Next[0] = -1;// 极其重要!!
    while(j < n){
        if(k == -1 || s[j] == s[k]){
            Next[++j] = ++k;
        }
        else k = Next[k];
    }
}
int main()
{
    while(~scanf("%s", s) && s[0] != '.'){
        int len = strlen(s);
        Get_Next(s);
        if(len % (len - Next[len]) == 0){
            printf("%d\n", len / (len - Next[len]));
        }
        else printf("1\n");
    }
    return 0;
}

**

K - Period

Description

For each prefix of a given string S with N characters (each character has an

ASCII code between 97 and 126, inclusive), we want to know whether the prefix

is a periodic string. That is, for each i (2 ≤ i ≤ N) we want to know the largest K

> 1 (if there is one) such that the prefix of S with length i can be written as AK ,

that is A concatenated K times, for some string A. Of course, we also want to

know the period K.

Input

 The input file consists of several test cases. Each test case consists of two

lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S.

The second line contains the string S. The input file ends with a line, having the

number zero on it.

Output

 For each test case, output “Test case #” and the consecutive test case

number on a single line; then, for each prefix with length i that has a period K >

1, output the prefix size i and the period K separated by a single space; the

prefix sizes must be in increasing order. Print a blank line after each test case.

Sample

Input 

3
aaa
12
aabaabaabaab
0

Output 

Test case #1
2 2
3 3
Test case #2
2 2
6 2
9 3
12 4

Hint

#include<bits/stdc++.h>
using namespace std;

const int N = 1e6 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
char s[N];
int Next[N];
void get_Next(char *s){
    int n = strlen(s);
    int j = 0, k = -1;
    Next[0] = -1;// really really重要!!莫忘记(T.T)
    while(j < n){
        if(k == -1 || s[j] == s[k]){
            Next[++j] = ++k;
        }
        else k = Next[k];
    }
}
int main()
{
    ios::sync_with_stdio(0);
    int n, j = 0;
    while(cin >> n && n){
        for(int i = 0; i < n; i++){
            cin >> s[i];
        }
        get_Next(s);
        j++;
        cout << "Test case #" << j << endl;
        for(int i = 2; i <= n; i++){
            if(i % (i - Next[i]) == 0 && i != (i - Next[i])){
                cout << i << " " << i / (i - Next[i]) << endl;
            }
        }
    }
    return 0;
}

**MARK

L - 数据结构实验之数组一:矩阵转置

Description

数组——矩阵的转置

给定一个m*n的矩阵(m,n<=100),求该矩阵的转置矩阵并输出。

Input

 输入包含多组测试数据,每组测试数据格式如下:

第一行包含两个数m,n

以下m行,每行n个数,分别代表矩阵内的元素。

(保证矩阵内的数字在int范围之内)

Output

 对于每组输出,输出给定矩阵的转置矩阵。两组输出之间用空行隔开。

Sample

Input 

2 3
1 2 3
4 5 6
1 1
1

Output 

1 4
2 5
3 6

1

Hint

#include<bits/stdc++.h>
using namespace std;

const int N = 1e2 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
int a[N][N];
int main()
{
    int m, n;
    while(cin >> m >> n){
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                cin >> a[i][j];
            }
        }
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(j == m - 1) cout << a[j][i] << endl;
                else cout << a[j][i] << " ";// 和行列没有关系,只是输出需要的位置的字符而已
            }
        }
        cout << endl;
    }
    return 0;
}

M - 数据结构实验之数组三:快速转置

Description


 

转置运算是一种最简单的矩阵运算,对于一个m*n的矩阵M( 1 = < m < = 10000,1 = < n < = 10000 ),它的转置矩阵T是一个n*m的矩阵,且T( i , j )=M( j , i )。显然,一个稀疏矩阵的转置仍然是稀疏矩阵。你的任务是对给定一个m*n的稀疏矩阵( m , n < = 10000 ),求该矩阵的转置矩阵并输出。矩阵M和转置后的矩阵T如下图示例所示。
   
   稀疏矩阵M                             稀疏矩阵T

Input

连续输入多组数据,每组数据的第一行是三个整数mu, nu, tu(tu <= 50),分别表示稀疏矩阵的行数、列数和矩阵中非零元素的个数,随后tu行输入稀疏矩阵的非零元素所在的行、列值和非零元素的值,同一行数据之间用空格间隔。(矩阵以行序为主序)

Output

输出转置后的稀疏矩阵的三元组顺序表表示。

Sample

Input 

3 5 5
1 2 14
1 5 -5
2 2 -7
3 1 36
3 4 28

Output 

1 3 36
2 1 14
2 2 -7
4 3 28
5 1 -5

Hint

 

N - 数据结构实验之数组二:稀疏矩阵

Description

对于一个n*n的稀疏矩阵M(1 <= n <= 1000),采用三元组顺序表存储表示,查找从键盘输入的某个非零数据是否在稀疏矩阵中,如果存在则输出OK,不存在则输出ERROR。稀疏矩阵示例图如下:

Input

连续输入多组数据,每组数据的第一行是三个整数mu, nu, tu(tu<=50),分别表示稀疏矩阵的行数、列数和矩阵中非零元素的个数,数据之间用空格间隔,随后tu行输入稀疏矩阵的非零元素所在的行、列值和非零元素的值,每组数据的最后一行输入要查询的数据k。

Output

输出查询结果,查找成功输出OK,找不到输出ERROR。

Sample

Input 

3 5 5
1 2 14
1 5 -5
2 2 -7
3 1 36
3 4 28
36

Output 

OK

Hint

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值