河南大学校园导航

实验内容:

面向学校,构建一个校院导游软件。用无向图表示所在学校的校院景点平面图,图中顶点表示主要景点,存放景点的编号、名称、简介等信息,图中边表示景点之间的道路,存放路径距离等信息。该软件具有以下基本功能,学生可自行扩展功能。

1)查询各景点的信息;

2)查询图中任意两个景点之间的所有可能路径;

3)查新图中任意两个景点之间的最短路径;

4)增加、删除、更新景点与道路信息

实验步骤:

1)查询各景点的信息;

2)查询图中任意两个景点之间的所有可能路径;

3)查新图中任意两个景点之间的最短路径;

4)增加、删除、更新景点与道路信息

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define INF 999999
//登陆
void login();

//游客模式
void vistor();

//管理员登陆
void adminLogin();

//管理员模式
void admin();

//首次使用程序的初始化
void init();

//增加场所
void addPlace();

//删除场所
void delPlace();

//添加道路
void addPath();

//删除道路
void delPath();

//修改场所信息
void modPlace();

//查看全部场所
void showInfo();

//求两景点最短距离
void Floyd(int start, int end);

//查看某场所详细介绍
void inquiryInfo(int n);

//安全地退出
void quit();

//读取文件
void readFile();

//保存文件
void writeFile();

typedef struct vertex Vertex;
struct vertex
{
    char name[100];
    char info[1000];
};
typedef int Edge;
struct map
{
    int placeNum;
    int pathNum;
    Vertex place[100];
    Edge path[100][100];
};
struct map hbuMap;

int flag, a, b, num, temp;
bool isAdmin = false;
FILE *pMap;


void writeFile()
{
    if ((pMap = fopen("map.dat", "wb")) == NULL)
    {
        fputs("打开map.dat文件失败\n", stderr);
        //stderr(标准错误),是不带缓冲的,这使得出错信息可以直接尽快地显示出来。
        exit(1);
    }
    rewind(pMap);
    //将文件内部的位置 指针重新指向一个流( 数据流/文件)的开头
    int size = sizeof(hbuMap);
    fwrite(&hbuMap, size, 1, pMap);
    fclose(pMap);
}

void readFile()
{
    if ((pMap = fopen("map.dat", "a+b")) == NULL)
    {
        fputs("打开map.dat文件失败\n", stderr);
        exit(1);
    }
    rewind(pMap);
    int size = sizeof(hbuMap);
    fread(&hbuMap, size, 1, pMap);
    fclose(pMap);
}

void login()
{

    printf("                ***************************** \n");
    printf("                *        1.游客登录           *\n");
    printf("                *        2.管理员登陆         *\n");
    printf("                *        3.退出              *\n");
    printf("                *****************************\n");
    scanf("%d", &flag);
    switch (flag)
    {
        case 1:
        {
            vistor();
            break;
        }
        case 2:
        {
            if (isAdmin == true)
                admin();
            adminLogin();
            break;
        }
        case 3:
        {
            quit();
            break;
        }
        default:
        {
            printf("输入错误,请重新输入!\n");
            login();
            break;
        }
    }
}

void init()
{
    hbuMap.placeNum = 31;
    hbuMap.pathNum = 56;
    for (int i = 0; i < 100; i++)
    {
        for (int j = 0; j < 100; j++)
        {
            hbuMap.path[i][j] = INF;
        }
    }
    strcpy(hbuMap.place[0].name, "1号教学楼");
    strcpy(hbuMap.place[0].info, "考试经常用到");
    strcpy(hbuMap.place[1].name, "2号教学楼");
    strcpy(hbuMap.place[1].info, "挺大");
    strcpy(hbuMap.place[2].name, "3号教学楼");
    strcpy(hbuMap.place[2].info, "装修不错");
    strcpy(hbuMap.place[3].name, "6号教学楼");
    strcpy(hbuMap.place[3].info, "建议别进厕所");
    strcpy(hbuMap.place[4].name, "曾宪梓楼");
    strcpy(hbuMap.place[4].info, "很多研究生");
    strcpy(hbuMap.place[5].name, "北苑");
    strcpy(hbuMap.place[5].info, "学校北边");
    strcpy(hbuMap.place[6].name, "东苑");
    strcpy(hbuMap.place[6].info, "学校东边");
    strcpy(hbuMap.place[7].name, "南苑");
    strcpy(hbuMap.place[7].info, "学校南边");
    strcpy(hbuMap.place[8].name, "中州路");
    strcpy(hbuMap.place[8].info, "学校大道");
    strcpy(hbuMap.place[9].name, "金明校区图书馆");
    strcpy(hbuMap.place[9].info, "自习很不错");
    strcpy(hbuMap.place[10].name, "计算机大楼");
    strcpy(hbuMap.place[10].info, "朴实无华");
    strcpy(hbuMap.place[11].name, "化学院");
    strcpy(hbuMap.place[11].info, "没去过");
    strcpy(hbuMap.place[12].name, "北苑餐厅");
    strcpy(hbuMap.place[12].info, "装修很好");
    strcpy(hbuMap.place[13].name, "东苑食堂");
    strcpy(hbuMap.place[13].info, "一般般");
    strcpy(hbuMap.place[14].name, "北大门");
    strcpy(hbuMap.place[14].info, "学校");
    strcpy(hbuMap.place[15].name, "物理学院");
    strcpy(hbuMap.place[15].info, "做实验");
    strcpy(hbuMap.place[16].name, "中州国际酒店");
    strcpy(hbuMap.place[16].info, "一般般");
    strcpy(hbuMap.place[17].name, "湖");
    strcpy(hbuMap.place[17].info, "天鹅很好看");
    strcpy(hbuMap.place[18].name, "软件学院");
    strcpy(hbuMap.place[18].info, "不知道和计算机有什么区别");
    strcpy(hbuMap.place[19].name, "4号教学楼");
    strcpy(hbuMap.place[19].info, "一楼两个教室,老杨讲高数的地方");
    strcpy(hbuMap.place[20].name, "志义体育场");
    strcpy(hbuMap.place[20].info, "听音乐");
    strcpy(hbuMap.place[21].name, "生科院");
    strcpy(hbuMap.place[21].info, "没去过");
    strcpy(hbuMap.place[22].name, "物理学院");
    strcpy(hbuMap.place[22].info, "没去过");
    strcpy(hbuMap.place[23].name, "校医院");
    strcpy(hbuMap.place[23].info, "没去过");
    strcpy(hbuMap.place[24].name, "北院餐厅");
    strcpy(hbuMap.place[24].info, "没去过。。。。");
    strcpy(hbuMap.place[25].name, "篮球场网球场");
    strcpy(hbuMap.place[25].info, "很好");
    strcpy(hbuMap.place[26].name, "东操场");
    strcpy(hbuMap.place[26].info, "跑步");
    strcpy(hbuMap.place[27].name, "树林3");
    strcpy(hbuMap.place[27].info, "没去过");
    strcpy(hbuMap.place[28].name, "树林4");
    strcpy(hbuMap.place[28].info, "没去过");
    strcpy(hbuMap.place[29].name, "树林5");
    strcpy(hbuMap.place[29].info, "没去过");
    strcpy(hbuMap.place[30].name, "树林6");
    strcpy(hbuMap.place[30].info, "没去过");


    hbuMap.path[0][1] = hbuMap.path[1][0] = 150;
    hbuMap.path[0][2] = hbuMap.path[2][0] = 144;
    hbuMap.path[1][2] = hbuMap.path[2][1] = 110;
    hbuMap.path[1][3] = hbuMap.path[3][1] = 75;
    hbuMap.path[1][4] = hbuMap.path[4][1] = 93;
    hbuMap.path[2][3] = hbuMap.path[3][2] = 42;
    hbuMap.path[3][4] = hbuMap.path[4][3] = 44;
    hbuMap.path[2][6] = hbuMap.path[6][2] = 169;
    hbuMap.path[2][8] = hbuMap.path[8][2] = 73;
    hbuMap.path[3][8] = hbuMap.path[8][3] = 87;
    hbuMap.path[4][5] = hbuMap.path[5][4] = 60;
    hbuMap.path[6][7] = hbuMap.path[7][6] = 139;
    hbuMap.path[6][8] = hbuMap.path[8][6] = 167;
    hbuMap.path[7][8] = hbuMap.path[8][7] = 20;
    hbuMap.path[8][9] = hbuMap.path[9][8] = 78;
    hbuMap.path[8][10] = hbuMap.path[10][8] = 190;
    hbuMap.path[7][10] = hbuMap.path[10][7] = 20;
    hbuMap.path[5][9] = hbuMap.path[9][5] = 134;
    hbuMap.path[9][11] = hbuMap.path[11][9] = 77;
    hbuMap.path[10][11] = hbuMap.path[11][10] = 114;
    hbuMap.path[10][12] = hbuMap.path[12][10] = 91;
    hbuMap.path[11][12] = hbuMap.path[12][11] = 96;
    hbuMap.path[5][13] = hbuMap.path[13][5] = 37;
    hbuMap.path[11][14] = hbuMap.path[14][11] = 39;
    hbuMap.path[5][11] = hbuMap.path[11][5] = 210;
    hbuMap.path[13][14] = hbuMap.path[14][13] = 202;
    hbuMap.path[13][15] = hbuMap.path[15][13] = 179;
    hbuMap.path[13][19] = hbuMap.path[19][13] = 93;
    hbuMap.path[14][15] = hbuMap.path[15][14] = 59;
    hbuMap.path[14][16] = hbuMap.path[16][14] = 56;
    hbuMap.path[19][21] = hbuMap.path[21][19] = 92;
    hbuMap.path[21][23] = hbuMap.path[23][21] = 82;
    hbuMap.path[21][22] = hbuMap.path[22][21] = 111;
    hbuMap.path[19][20] = hbuMap.path[20][19] = 105;
    hbuMap.path[20][22] = hbuMap.path[22][20] = 80;
    hbuMap.path[19][17] = hbuMap.path[17][19] = 178;
    hbuMap.path[22][24] = hbuMap.path[24][22] = 84;
    hbuMap.path[22][17] = hbuMap.path[17][22] = 91;
    hbuMap.path[15][16] = hbuMap.path[16][15] = 53;
    hbuMap.path[15][17] = hbuMap.path[17][15] = 57;
    hbuMap.path[16][18] = hbuMap.path[18][16] = 115;
    hbuMap.path[17][18] = hbuMap.path[18][17] = 108;
    hbuMap.path[17][24] = hbuMap.path[24][17] = 114;
    hbuMap.path[18][24] = hbuMap.path[24][18] = 102;
    hbuMap.path[24][25] = hbuMap.path[25][24] = 24;
    hbuMap.path[24][30] = hbuMap.path[30][24] = 44;
    hbuMap.path[18][25] = hbuMap.path[25][18] = 15;
    hbuMap.path[18][26] = hbuMap.path[26][18] = 70;
    hbuMap.path[25][26] = hbuMap.path[26][25] = 5;
    hbuMap.path[25][30] = hbuMap.path[30][25] = 49;
    hbuMap.path[30][29] = hbuMap.path[29][30] = 92;
    hbuMap.path[25][29] = hbuMap.path[29][25] = 20;
    hbuMap.path[28][29] = hbuMap.path[29][28] = 20;
    hbuMap.path[26][27] = hbuMap.path[27][26] = 10;
    hbuMap.path[26][28] = hbuMap.path[28][26] = 10;
    hbuMap.path[27][28] = hbuMap.path[28][27] = 134;

    writeFile();
}

void showInfo()
{
    printf("****景点目录****\n");
    for (num = 0; num < hbuMap.placeNum; num++)
        printf("【%d】 %s\n", num + 1, hbuMap.place[num].name);
    printf("**************\n");
}

void inquiryInfo(int n)
{
    printf("景点编号:%d\n景点名称:%s\n景点介绍:%s\n", n, hbuMap.place[n - 1].name, hbuMap.place[n - 1].info);
}

void Floyd(int start, int end)
{
    printf("起始地:%s,目的地:%s\n", hbuMap.place[start - 1].name, hbuMap.place[end - 1].name);
    if (hbuMap.placeNum <= 0)
    {
        printf("地图中无任何景点!\n");
        return;
    }
    if (hbuMap.placeNum == 1)
    {
        printf("地图中只有一个景点,无法查询!\n");
        return;
    }
    if (hbuMap.pathNum <= 0)
    {
        printf("地图中无道路!\n");
        return;
    }
    int e[100][100];//邻接矩阵
    int pre[100][100];//存路径
    int i, j, k;
    //初始化
    for (i = 0; i < hbuMap.placeNum; i++)
        for (j = 0; j < hbuMap.placeNum; j++)
        {
            e[i][j] = hbuMap.path[i][j];
            pre[i][j] = j;
        }
    //更新路径
    for (k = 0; k < hbuMap.placeNum; k++)
        for (i = 0; i < hbuMap.placeNum; i++)
            for (j = 0; j < hbuMap.placeNum; j++)
            {

                if (e[i][j] > e[i][k] + e[k][j])
                {
                    e[i][j] = e[i][k] + e[k][j];
                    pre[i][j] = pre[i][k];
                }
            }
    // 打印路径
    // 无穷大,无路径
    if (e[end - 1][start - 1] == INF)
    {
        printf("从%s无法到达%s\n", hbuMap.place[start - 1].name, hbuMap.place[end - 1].name);
    } else
    {
        printf("%s到%s的最短路径路程为:%d米\n", hbuMap.place[start - 1].name, hbuMap.place[end - 1].name,
               e[end - 1][start - 1]);
        printf("路径为:\n%s", hbuMap.place[start - 1].name);
        if (pre[start - 1][end - 1] == end - 1)
        { // 如果可以直连
            printf("->%s", hbuMap.place[end - 1].name);
        } else
        {                   //需要绕路
            temp = start - 1; //初始化temp为终点
            while (temp != end - 1)
            {
                printf("->%s", hbuMap.place[pre[temp][end - 1]].name);
                temp = pre[temp][end - 1];
            }
        }
        printf("\n");
    }
}

void vistor()
{
    printf("==========游客============\n"
           "        0.返回         \n"
           "        1.查询校内路线\n"
           "        2.景点信息\n"
           "        3.退出\n"
           "=========请输入序号========\n");
    scanf("%d", &flag);
    switch (flag)
    {
        case 0:
        {
            login();
        }
        case 1:
        {
            int start, end;
            showInfo();

            printf("请输入起始地编号\n");
            scanf("%d", &start);
            printf("请输入目的地编号\n");
            scanf("%d", &end);
            if (start < 1 || start > hbuMap.placeNum || end < 1 || end > hbuMap.placeNum || start == end)
            {
                printf("起始点/结束点不存在或者起始地不能与目的地相同!");
                vistor();
            }
            Floyd(start, end);
            vistor();
            break;
        }
        case 2:
        {
            showInfo();
            printf("请输入景点编号\n");
            scanf("%d", &num);
            inquiryInfo(num);
            vistor();
            break;
        }
        case 3:
        {
            quit();
            break;
        }
        default:
        {
            printf("输入错误,请重新输入!\n");
            vistor();
        }
    }
}

void quit()
{
    float y, x, z, f;
    for (y = 1.5f; y > -1.5f; y -= 0.1f)
    {
        for (x = -1.5f; x < 1.5f; x += 0.05f)
        {
            z = x * x + y * y - 1;
            f = z * z * z - x * x * y * y * y;
            putchar(f <= 0.0f ? "*********"[(int) (f * -8.0f)] : ' ');
        }
        putchar('\n');
    }
    getchar();
    if (isAdmin == true)
        writeFile();
    exit(0);
}

void adminLogin()
{
    printf("=========管理员登录======\n");
    printf("请输入管理员密码:\n");
    printf("提示:密码是336699\n");
    char password[18];
    getPassword:
    scanf("%s", password);
    if (strcmp(password, "336699") == 0)
    {
        printf("登录成功!\n");
        isAdmin = true;
        admin();
    } else
    {
        printf("密码错误\n请重新输入密码:\n");
        goto getPassword;
    }
}

void admin()
{
    printf("=========管理员系统======\n");
    showInfo();
    adminFlag:

    printf("=======请输入序号=========\n"
           "1.增加景点\n"
           "2.删除景点\n"
           "3.增加道路\n"
           "4.删除道路\n"
           "5.修改景点信息\n"
           "6.进入游客系统\n"
           "7.退出\n"
           "=========================\n");
    scanf("%d", &flag);
    switch (flag)
    {
        case 1:
        {
            addPlace();
            break;
        }
        case 2:
        {
            delPlace();
            break;
        }
        case 3:
        {
            addPath();
            break;
        }
        case 4:
        {
            delPath();
            break;
        }
        case 5:
        {
            modPlace();
            break;
        }

        case 6:
        {
            vistor();
            break;
        }
        case 7:
        {
            quit();
            break;
        }
        default:
        {
            printf("输入错误,请重新输入!");
            goto adminFlag;
        }
    }
}


void addPlace()
{
    if (hbuMap.placeNum >= 100)
    {
        printf("空间已满,无法添加!\n");
        return;
    }
    showInfo();
    char newName[50];
    char newInfo[200];
    printf("请输入您要增加的景点名称:\n");
    scanf("%s", newName);
    printf("请输入%s的景点信息简介\n", newName);
    scanf("%s", newInfo);
    strcpy(hbuMap.place[hbuMap.placeNum].name, newName);
    strcpy(hbuMap.place[hbuMap.placeNum].info, newInfo);
    hbuMap.placeNum++;
    printf("景点添加成功!\n"
           "1.继续添加景点.\n"
           "2.返回上一界面.\n");
    scanf("%d", &flag);
    if (flag == 1)
        addPlace();
    admin();
}

void addPath()
{
    if (hbuMap.placeNum <= 0)
    {
        printf("地图中无任何景点\n");
        admin();
    }
    if (hbuMap.placeNum == 1)
    {
        printf("当前系统中只有一个景点,无法添加道路!\n");
        admin();
    }
    showInfo();
    printf("请输入要增加道路的两个景点编号:\n");
    add:
    scanf("%d%d", &a, &b);
    if (a < 1 || a > hbuMap.placeNum || b < 1 || b > hbuMap.placeNum || a == b)
    {
        if (a == b)
            printf("请勿输入两个相同编号,重新输入!\n");
        else
            printf("编号不合法,两个编号都应位于1~%d之间!\n", hbuMap.placeNum);
        goto add;
    }
    if (hbuMap.path[a - 1][b - 1] < INF)
    {
        printf("%s与%s之间已经含有道路,无法再添加!\n", hbuMap.place[a - 1].name, hbuMap.place[b - 1].name);
        admin();
    } else
    {
        int distance;
        printf("请输入%s与%s之间道路的长度:\n", hbuMap.place[a - 1].name, hbuMap.place[b - 1].name);
        scanf("%d", &distance);
        undis:
        if (distance <= 0 || distance >= INF)
        {
            printf("长度不合法,请重新输入!\n");
            scanf("%d", &distance);
            goto undis;
        }
        hbuMap.path[a - 1][b - 1] = hbuMap.path[b - 1][a - 1] = distance;
        hbuMap.pathNum++;
        printf("%s与%s之间道路添加成功!\n", hbuMap.place[a - 1].name, hbuMap.place[b - 1].name);
    }
    printf("继续添加?【是1/否0】\n");
    scanf("%d", &flag);
    if (flag == 1)
        addPath();
    admin();
}

void delPlace()
{
    if (hbuMap.placeNum <= 0)
    {
        printf("地图中无任何景点,无法删除!\n");
        return;
    }
    showInfo();
    printf("请输入您要删除的景点编号:\n");
    scanf("%d", &a);
    while (a > hbuMap.placeNum || a < 1)
    {
        printf("编号输入有误,编号应位于1~%d之间,重新输入!\n", hbuMap.placeNum);
        scanf("%d", &a);
    }
    printf("您要删除的景点名称为:%s,是否确认删除该景点?确认请输入1 \n", hbuMap.place[a - 1].name);
    scanf("%d", &flag);
    if (flag == 1)
    {
        int i, j;
        int count = 0;
        //数一下有多少条相关的道路
        for (i = 0; i < hbuMap.placeNum; i++)
            if (hbuMap.path[a - 1][i] != INF)
                count++;
        //其他景点往前移动
        for (i = a - 1; i < hbuMap.placeNum; i++)
            hbuMap.place[i] = hbuMap.place[i + 1];
        //景点移动后,修改对应道路
        //横向
        for (i = 0; i < hbuMap.placeNum; i++)
            for (j = a - 1; j < hbuMap.placeNum; j++)
                hbuMap.path[i][j] = hbuMap.path[i][j + 1];
        //纵向
        for (i = 0; i < hbuMap.placeNum; i++)
            for (j = a - 1; j < hbuMap.placeNum; j++)
                hbuMap.path[j][i] = hbuMap.path[j + 1][i];
        hbuMap.placeNum--;
        hbuMap.pathNum -= count;
    } else
        return;
    printf("景点删除成功!\n");
    printf("继续删除?【是1/否0】\n");
    scanf("%d", &flag);
    if (flag == 1)
        delPlace();
    showInfo();
    admin();
}

void delPath()
{
    if (hbuMap.pathNum <= 0)
    {
        printf("地图中无任何道路!\n");
        admin();
    }
    showInfo();
    printf("目前总共有%d条道路\n", hbuMap.pathNum);
    printf("请输入要删除道路的两个景点编号:\n");
    scanf("%d %d", &a, &b);
    while (a < 1 || a > hbuMap.placeNum || b < 1 || b > hbuMap.placeNum || a == b)
    {
        if (a == b)
            printf("请勿输入两个相同编号,重新输入!\n");
        if (a < 1 || a > hbuMap.placeNum || b < 1 || b > hbuMap.placeNum)
            printf("编号不合法,两个编号都应位于1~%d之间,请重新输入!\n", hbuMap.placeNum);
        scanf("%d %d", &a, &b);
    }
    if (hbuMap.path[a - 1][b - 1] >= INF)
    {
        printf("%s与%s之间不存在道路!\n", hbuMap.place[a - 1].name, hbuMap.place[b - 1].name);
        admin();
    } else
    {
        printf("确认删除%s与%s之间的道路吗【确认1/否认0】 \n", hbuMap.place[a - 1].name, hbuMap.place[b - 1].name);
        scanf("%d", &flag);
        if (flag == 1)
        {
            hbuMap.path[a - 1][b - 1] = hbuMap.path[b - 1][a - 1] = INF;
            hbuMap.pathNum--;
            printf("道路删除成功!\n");
        } else
            admin();
    }
    printf("继续删除?【确认1/否认0】\n");
    int f;
    scanf("%d", &f);
    if (f == 1)
        delPath();
    admin();
}

void modPlace()
{
    if (hbuMap.place <= 0)
    {
        printf("地图中无任何景点,请先添加景点!\n");
        return;
    }
    showInfo();
    printf("请输入您要修改信息的景点编号:\n");
    scanf("%d", &num);
    while (num < 1 || num > hbuMap.placeNum)
    {
        printf("编号输入有误,编号应位于1~%d之间,重新输入!\n", hbuMap.placeNum);
        scanf("%d", &num);
    }
    char newName[100];
    char newInfo[1000];
    printf("该景点当前的名字为%s,请输入此景点更改后的名字:\n", hbuMap.place[num - 1].name);
    scanf("%s", newName);
    printf("该景点当前的信息简介为:\n%s\n请输入此景点更改后的信息简介:\n", hbuMap.place[num - 1].info);
    scanf("%s", newInfo);
    strcpy(hbuMap.place[num - 1].name, newName);
    strcpy(hbuMap.place[num - 1].info, newInfo);
    printf("景点信息修改成功!\n");
    admin();
}

int main()
{
    printf("是否是第一次使用?【是1/否0】\n");
    scanf("%d", &flag);
    if (flag == 1)
        init();
    else
        readFile();
    login();
    return 0;
}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

henu-zwh

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值