【数据结构】停车场管理系统程序设计

这篇具有很好参考价值的文章主要介绍了【数据结构】停车场管理系统程序设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

说明:该程序设计采用常见基础的数据结构栈和队列实现了一个简单停车场管理系统。在具体设计中,实现了系统页面和停车场的示意图显示,通过调用顺序栈和链队的相关函数,模拟了实际停车场的运营流程。


目录

1 任务内容

2 需求分析

2.1 功能需求

2.2 输入输出需求

3 概要设计

3.1 抽象数据类型

3.2 具体功能函数

4 详细代码

5 使用说明

6 测试结果与分析

7 总结感悟


1 任务内容

任务描述:设停车场(如下图所示)内只有一个可停放几量汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已经停满几量汽车,则后来的汽车只能在门外的便道上等候,一旦停车场内有车开走,则排在便道上的第一辆汽车即可开入;当停车场内某车辆要离开时,由于停车场是狭长的通道,在它之后开入车场的车辆必须先退出车场为它让路,待该车辆开出大门外后,为它让路的车辆再按原次序进入车场。在这里假设汽车不能从便道上开走。试设计一个停车场管理程序(这里只是一个假想的停车场管理,并不代表实际的停车场管理)。

数据结构程序设计停车场信息统计,数据结构,数据结构

分析提示:汽车在停车场内进出是按照栈的运算方式来实现的,先到的先进停车场;停车场的汽车离开停车场时,汽车场内其它汽车为该辆汽车让路,也是按栈的方式进行;汽车在便道上等候是按队列的方式进行的。因此,将停车场设计成一个栈,汽车让路也需要另一个栈来协助完成,汽车进出便道用队列来实现。

基本要求

1)接受命令和车号,若是汽车要进停车场,先判断停车场栈是否满,若不满,则汽车入栈,否则汽车进入便道队列等候。

2)若是汽车要离开停车场,为给汽车让路,将停车场栈上若干辆汽车入临时栈,等这辆车出停车场后,临时栈中的汽车出栈,在回到停车场栈,然后看便道队列是否为空,若不空则说明有汽车等候,从队头取出汽车号,让该车进入停车场栈。

3)重复1),2)直到为退出命令(车号为0或负数)。

数据结构:本设计中,栈采用顺序栈结构,队列用链式存储结构。

核心知识:栈和队列。

2 需求分析

2.1 功能需求

一、界面设计

1. 停车场管理系统界面

2. 停车场字符模拟示意图

2. 便道字符模拟示意图

二、停车场管理

1. 车辆停放:包括车辆停放操作、便道等候操作

2. 车辆离开:包括车辆离开操作、便道车辆停放操作

3. 停车场状态:显示当前停车场和便道的车辆状态

4. 打印停车场车辆信息:显示当前停车场示意图

5. 打印便道车辆信息:显示当前便道示意图

2.2 输入输出需求

一、系统界面

输出:“欢迎使用STRANGEX-03停车场管理系统”字样、停车场管理功能模块等内容。

输入:单个字符“A”“B”“C”等内容表示要选择的功能模块或退出系统的操作。

输出:执行对应功能模块的相关操作。

二、车辆停放模块(在系统界面输入A

输出:当前停车场和便道的车辆状态,提示字样如“当前空余车位为X,便道上共有X辆车在等待,您确定要停车吗”。

(一)同意停放车辆

输入:单个字符“Y”表示同意。

输出:“请输入您的车辆编号”字样

输入:5位整型数字表示车辆编号

输出:“您的车辆已停放到停车场”或“您的车辆正在便道等待”

(二)拒绝停放车辆

输入:单个字符“N”表示拒绝。

输出:返回系统界面

三、车辆离开模块(在系统界面输入B

输出:提示字样如“请输入您的车辆编号”

输入:5位整型数字表示车辆编号

(一)便道上没有车辆

输出:执行操作后提示“该车辆已离开,X车辆已停入停车场,便道现有X辆车在等待”,

(二)便道上有车辆

输出:“该车辆已离开停车场”

四、停车场状态模块(在系统界面输入C

输出:当前停车场和便道的车辆状态,字样如“停车场共有%d个车位,当前空余车位为%d,便道上共有%d辆车在等待”

五、停车场车辆信息模块(在系统界面输入D

输出:当前停车场的模拟示意图

六、便道车辆信息模块(在系统界面输入E

输出:当前便道的模拟示意图

3 概要设计

3.1 抽象数据类型

本程序共设计三个抽象数据类型分别表示停车场栈、通道车辆结点和便道队列。

//停车场栈

typedef struct{
    int data[StackSize];
    int top;
} SqStack;

//通道车辆结点

typedef struct linked_queue{
    int data;
    struct linked_queue *next;
} DataNode;

//便道队列

typedef struct{
    DataNode *front;
    DataNode *rear ;
} LinkQuNode;

3.2 具体功能函数

本程序共有22个功能函数,具体包括4个界面设计函数、5个停车场管理函数、7个栈操作函数、6个队列操作函数。

//界面设计函数

void MainMenu();                            //主菜单界面
void TouchMenu(SqStack *&s,LinkQuNode *&q); //菜单触控操作
void ParkingLot(SqStack *s);                //停车场模拟界面
void WaitingRoad(LinkQuNode *&q);           //便道模拟界面

//停车场管理函数

void ToPark(SqStack *&s,LinkQuNode *&q);    //车辆停放操作
void ToLeave(SqStack *&s,LinkQuNode *&q);   //车辆离开操作
void GetStatus(SqStack *s,LinkQuNode *q);   //显示当前停车场和便道状态
void GetParking(SqStack *s);                //打印当前停车场车辆信息
void GetWaiting(LinkQuNode *&q);            //打印当前便道车辆信息

//栈操作函数

void InitStack(SqStack *&s);          //初始化栈
void DestroyStack(SqStack *&s);       //销毁栈
bool StackEmpty(SqStack *s);          //判断栈是否为空
bool Push(SqStack *&s,int e);         //入栈操作
bool Pop(SqStack *&s,int &e);         //出栈操作
bool GetTop(SqStack *s,int &e);       //获取栈顶元素
int CountStack(SqStack *s);           //计算栈内元素个数

//队列操作函数

void InitQueue(LinkQuNode *&q);        //初始化队列
void DestroyQueue(LinkQuNode *&q);     //销毁队列
bool QueueEmpty(LinkQuNode *q);        //判断队列是否为空
bool enQueue(LinkQuNode *&q,int e);    //入队操作
bool deQueue(LinkQuNode *&q,int &e);   //出队操作
int CountQueue(LinkQuNode *q);         //计算队列内元素个数

4 详细代码

#include<bits/stdc++.h>
using namespace std;
const int StackSize=10;

//抽象数据类型
//停车场栈
typedef struct{
    int data[StackSize];
    int top;
} SqStack;

//便道车辆结点
typedef struct linked_queue{
    int data;
    struct linked_queue *next;
} DataNode;

//通道队列
typedef struct{
    DataNode *front;
	DataNode *rear ;
} LinkQuNode;



//具体功能函数列表
//界面设计函数
void MainMenu();
void TouchMenu(SqStack *&s,LinkQuNode *&q);
void ParkingLot(SqStack *s);
void WaitingRoad(LinkQuNode *&q);

//停车场管理函数
void ToPark(SqStack *&s,LinkQuNode *&q);
void ToLeave(SqStack *&s,LinkQuNode *&q);
void GetStatus(SqStack *s,LinkQuNode *q);
void GetParking(SqStack *s);
void GetWaiting(LinkQuNode *&q);

//栈操作函数
void InitStack(SqStack *&s);
void DestroyStack(SqStack *&s);
bool StackEmpty(SqStack *s);
bool Push(SqStack *&s,int e);
bool Pop(SqStack *&s,int &e);
bool GetTop(SqStack *s,int &e);
int CountStack(SqStack *s);

//队列操作函数
void InitQueue(LinkQuNode *&q);
void DestroyQueue(LinkQuNode *&q);
bool QueueEmpty(LinkQuNode *q);
bool enQueue(LinkQuNode *&q,int e);
bool deQueue(LinkQuNode *&q,int &e);
int CountQueue(LinkQuNode *q);



int main(){
	SqStack *park;//定义停车场栈
	LinkQuNode *wait;//定义通道队列
	InitStack(park);
	InitQueue(wait);
	//调试专用数据
	Push(park,12345);
	Push(park,67890);
	Push(park,63465);
	Push(park,89986);
	Push(park,53845);
	Push(park,65374);
	Push(park,15555);
	Push(park,25389);
	Push(park,24389);
	TouchMenu(park,wait);
	return 0;
}

//主菜单页面
void MainMenu(){
	printf("      * * * * * * * * * * * * * * * * * * *\n");
	printf("      * 欢迎使用STRANGEX-03停车场管理系统 *\n");
	printf("      * * * * * * * * * * * * * * * * * * *\n");
	printf("      *      [A]车辆停放模块              *\n");
	printf("      *      [B]车辆离开模块              *\n");
	printf("      *      [C]显示当前停车场运营状态    *\n");
	printf("      *      [D]打印停车场内的车辆信息    *\n");
	printf("      *      [E]打印便道上的车辆信息      *\n");
	printf("      *      [Z]退出系统                  *\n");
	printf("      * * * * * * * * * * * * * * * * * * *\n");
	printf("请输入字母选择你要使用的功能模块:");
}

//菜单触控
void TouchMenu(SqStack *&s,LinkQuNode *&q){
	char c;
	MainMenu();
	while(scanf("%c",&c)){
		switch(c){
			case 'A':
				ToPark(s,q);
				MainMenu();
				break;
			case 'B':
				ToLeave(s,q);
				MainMenu();
				break;
			case 'C':
				GetStatus(s,q);
				MainMenu();
				break;
			case 'D':
				GetParking(s);
				MainMenu();
				break;
			case 'E':
				GetWaiting(q);
				MainMenu();
				break;
			case 'Z':
				printf("\n欢迎再次使用STRANGEX-03停车场管理系统,再见!");
				return;
			default:
				printf("请输入正确的字母:");
		}
		c=getchar();//消除回车对程序的影响
	}
}

//停车场模拟界面
void ParkingLot(SqStack *s){
	printf("    @ @ @ @ @ @ @       ↑\n");
	for(int i=0;i<StackSize;i++){
		printf("    @ ");
		if(i<CountStack(s)){
			printf("车辆%d",s->data[i]);
			printf(" @");
		}
		else{
			printf("          @");
			
		}
		if(i==0){
			printf("       北");
		}
		else if(i==StackSize-2){
			printf("       ↓");
		}
		else if(i==StackSize-1){
			printf("       南");
		}
		else if(i==StackSize/2-1){
			printf("  停车场示意图");
		}
		printf("\n");
	}
}

//便道模拟界面 
void WaitingRoad(LinkQuNode *&q){
	
	printf("        ");
	for(int i=0;i<CountQueue(q);i++){
		printf("@ @ @ @ @ @ ");
	}
	printf("@ @\n");
	printf(" 出口 ← ");
	DataNode *car=q->front;
	int k=0;
	if(car!=NULL){
		while(car->next!=NULL){
			printf(" | 车辆%d",car->data);
			car=car->next;
		}
		printf(" | 车辆%d | ",car->data);
	}
	else {
		printf("   ");
	}
	printf(" ← 入口     便道示意图\n");
	printf("        ");
	for(int i=0;i<CountQueue(q);i++){
		printf("@ @ @ @ @ @ ");
	}
	printf("@ @\n");
}



//车辆停放
void ToPark(SqStack *&s,LinkQuNode *&q){
	printf("\n※当前功能模块:[A]车辆停放模块\n");
	printf("---------------------------------------------------------------------\n");
	printf("当前空余车位为%d,便道上共有%d辆车在等待,您确定要停车吗?\n",StackSize-CountStack(s),CountQueue(q));
	int c;
	printf("请输入[Y/N]:");
	scanf("%c",&c);
	c=getchar();
	if(c=='Y'){
		int carNo;
		printf("请输入车辆编号:");
		scanf("%d",&carNo);
		if(Push(s,carNo)){
			printf("车辆%d已成功停放在停车场\n",carNo);
		}
		else{
			enQueue(q,carNo);
			printf("停车场已满,车辆%d正在便道上等候\n",carNo);
		}
	}
	else if(c=='N'){
		printf("您已确认不停车,自动返回主菜单\n");
	}
	else if(c!='N') {
		printf("输入错误,自动返回主菜单\n");
	}
	printf("---------------------------------------------------------------------\n");
	printf("\n");
	return;
}

//车辆离开
void ToLeave(SqStack *&s,LinkQuNode *&q){
	printf("\n※当前功能模块:[B]车辆离开模块\n");
	printf("---------------------------------------------------------------------\n");
	int carNo;
	int No=-1;
	printf("请输入您的车辆编号:");
	scanf("%d",&carNo);
	for(int i=0;i<CountStack(s);i++){
		if(carNo==s->data[i]){
			No=i;
			break;
		}
	}
	if(No==-1){
		printf("对不起,没有找到您的车辆,自动返回主菜单\n");
	}
	else {
		SqStack *temp;
		int e;
		InitStack(temp);
		int x=CountStack(s);
		for(int i=x-1;i>No;i--){
			Pop(s,e);
			Push(temp,e);
		}
		Pop(s,e);
		for(int i=x-1;i>No;i--){
			Pop(temp,e);
			Push(s,e);
		}
		if(!QueueEmpty(q)){
			deQueue(q,e);
			Push(s,e);
			printf("车辆%d已离开,车辆%d已成功停放在停车场,便道还有%d辆车在等待\n",carNo,e,CountQueue(q)); 
		}
		else {
			printf("车辆%d已离开停车场\n",carNo);
		}
	}
	printf("---------------------------------------------------------------------\n");
	printf("\n");
	return;
}

//停车场状态
void GetStatus(SqStack *s,LinkQuNode *q){
	printf("\n※当前功能模块:[C]显示当前停车场运营状态\n");
	printf("---------------------------------------------------------------------\n");
	printf("停车场共有%d个车位,当前空余车位为%d,便道上共有%d辆车在等待\n",StackSize,StackSize-CountStack(s),CountQueue(q));
	printf("---------------------------------------------------------------------\n");
	printf("\n");
	return;
}

//打印停车场车辆信息
void GetParking(SqStack *s){
	printf("\n※当前功能模块:[D]打印停车场内的车辆信息\n");
	printf("---------------------------------------------------------------------\n");
	ParkingLot(s);
	printf("---------------------------------------------------------------------\n");
	printf("\n");
}

//打印便道车辆信息
void GetWaiting(LinkQuNode *&q){
	printf("\n※当前功能模块:[E]打印便道上的车辆信息\n");
	printf("---------------------------------------------------------------------\n");
	WaitingRoad(q); 
	printf("---------------------------------------------------------------------\n");
	printf("\n");
}



//栈操作函数
//初始化栈
void InitStack(SqStack *&s){
	s=(SqStack *)malloc(sizeof(SqStack));
	s->top=-1;
}

//销毁栈
void DestroyStack(SqStack *&s){
	free(s);
}

//判断栈是否为空
bool StackEmpty(SqStack *s){
	return (s->top==-1);
}

//进栈
bool Push(SqStack *&s,int e){
	if(s->top==StackSize-1)
		return false;
	s->top++;
	s->data[s->top]=e;
	return true;
}

//出栈
bool Pop(SqStack *&s,int &e){
	if(s->top==-1)
		return false;
	e=s->data[s->top];
	s->top--;
	return true;
}

//取栈顶元素
bool GetTop(SqStack *s,int &e){
	if(s->top==-1)
		return false;
	e=s->data[s->top];
	return true;
}

//返回栈的元素个数
int CountStack(SqStack *s){
	return s->top+1;
}



//队列操作函数
//初始化
void InitQueue(LinkQuNode *&q){
    q=(LinkQuNode *)malloc(sizeof(LinkQuNode));
    q->front=q->rear=NULL;
}

//销毁队列
void DestroyQueue(LinkQuNode *&q){
    DataNode *pre=q->front,*p;
    if(pre!=NULL){
        p=pre->next;
        while(p!=NULL){
            free(pre);
            pre=p;
            p=p->next;
        }
        free(pre);
    }
    free(q);
}

//判断队列是否为空
bool QueueEmpty(LinkQuNode *q){
	return q->rear==NULL;
}

//进队列
bool enQueue(LinkQuNode *&q,int e){
    DataNode *p;
    p=(DataNode *)malloc(sizeof(DataNode));
    p->data=e;
    p->next=NULL;
    if(q->rear==NULL)
        q->front=q->rear=p;
    else{
        q->rear->next=p;
        q->rear=p;
    }
    return true;
}

//出队列
bool deQueue(LinkQuNode *&q,int &e){
    DataNode *t;
    if(q->rear==NULL)
        return false;
    t=q->front;
    if(q->front==q->rear)
        q->front=q->rear=NULL;
    else
        q->front=q->front->next;
    e=t->data;
    free(t);
    return true;
}

//返回队列的元素个数
int CountQueue(LinkQuNode *q){
	int sum=1;
	DataNode *a=q->front,*b=q->rear;
	if(a==NULL&&a==b)
		return 0;
	while(a!=b){
		sum++;
		a=a->next;
	}
	return sum;
}

5 使用说明

数据结构程序设计停车场信息统计,数据结构,数据结构

系统界面共有五个功能选项和一个退出系统选项,选择不同选项根据提示进入下一步操作:

选择[A]:进入车辆停放模块。

选择[B]:进入车辆离开模块。

选择[C]:进入显示当前停车场运营状态模块。

选择[D]:进入打印停车场内的车辆信息模块。

选择[E]:进入打印便道上的车辆信息模块。

选择[Z]:显示“欢迎再次使用STRANGEX-03停车场管理系统,再见!”并退出系统,结束程序。

6 测试结果与分析

为便于调试显示,前期对停车场栈进行以下操作,存入部分数据。

Push(park,12345);
Push(park,25345);
Push(park,67890);
Push(park,89986);
Push(park,53845);
Push(park,65374);
Push(park,15555);
Push(park,25389);
Push(park,24389);
输入数据 调试截图

A

Y

54321

数据结构程序设计停车场信息统计,数据结构,数据结构

A

Y

89745

数据结构程序设计停车场信息统计,数据结构,数据结构

A

Y

88888

数据结构程序设计停车场信息统计,数据结构,数据结构
C 数据结构程序设计停车场信息统计,数据结构,数据结构
D 数据结构程序设计停车场信息统计,数据结构,数据结构
E 数据结构程序设计停车场信息统计,数据结构,数据结构

B

54321

数据结构程序设计停车场信息统计,数据结构,数据结构
E 数据结构程序设计停车场信息统计,数据结构,数据结构
Z 数据结构程序设计停车场信息统计,数据结构,数据结构

 

7 总结感悟

在完成栈和队列知识梳理后进行本次程序设计,进一步巩固了对栈和队列的理解。题目本身难度不大,主要就根据任务的意思模拟了相关操作就能实现。

此次设计中主要遇到的一个比较大的问题是,无法实现向栈和队列中添加string类型数据,运行到相关Push操作和enQueue操作时提示“Thread 1 received signal SIGSEGV, segmentation fault.”,也就导致了标识车辆时只能使用整型数字表示车辆编号,而无法使用string字符串(即模拟车牌号)进行标识。这个问题目前仍未解决,网上也找不到相关的资料,可待后续再研究一下。

本次为了提升对于栈和队列应用的理解,没有使用C++内置的STL栈和队列。但其实对于相关的函数可以使用类进行封装,此前在Java中学习了面向对象的相关知识,但在C++中还未实现过,这也是后续可以学习实践的方向。文章来源地址https://www.toymoban.com/news/detail-767968.html

到了这里,关于【数据结构】停车场管理系统程序设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 停车场管理系统

    开发   以下为停车场管理系统的代码:   首先定义Car类,记录车辆信息:   ```java public class Car {     private String plateNumber;  // 车牌号     private long enterTime;  // 进入停车场时间     private long exitTime;  // 离开停车场时间       public Car(String plateNumber, long enterTime) {      

    2024年02月09日
    浏览(40)
  • C#停车场管理系统

    现如今随着经济的发展, 私家车越来越多, 系统管理停车场变得尤为重要。所以我写了这个系统用来系统化的管理停车场的车辆的停入、驶出和计费,停车位的使用情况,停车证件的信息管理以及工作员工的信息管理,使得停车场的管理可以变的更加的方便快捷和人性化。

    2024年02月07日
    浏览(46)
  • 停车场管理系统(C++)

    大二写的肯定会有很多很多很多缺点~希望大佬们能指出~给大家提供一个可以改的一个小东西,改成其他的什么什么也是可以的~有bug在评论区里说一下~952行~基本重要的都有注释~ 本“项目”实现了: 1.大中小车型分类 2.进场候车道 3.时间的自动提取 4.车牌的判定 5.查询、进车

    2024年01月16日
    浏览(50)
  • 停车场管理系统(C语言)

    1、问题描述 设有一个可以停放n辆汽车的狭长停车场,它只有一个大门可以供车辆进出。车辆按到达停车场时间的早晚依次从停车场最里面向大门口处停放(最先到达的第一辆车放在停车场的最里面)。如果停车场已放满n辆车,则后来的车辆只能在停车场大门外的便道上等待

    2024年02月04日
    浏览(39)
  • 用JAVA实现停车场管理系统

    该程序使用ArrayList存储停车记录,并通过switch-case语句实现菜单选择功能。主要功能包括: 停车:输入车牌号和进入时间,自动分配停车位编号, 结算:根据停车位编号计算停车费用,计费标准为停车时长(秒)乘以每秒费用0.05元,同时记录车辆离开时间和费用; 查看记录

    2024年02月11日
    浏览(40)
  • 基于python的停车场管理系统的设计与实现/智能停车管理系统

    车位信息 是 停车场供应用户 必不可少的一个部分。在 停车场发展 的整个过程中, 车位信息 担负着最重要的角色。为满足如今日益复杂的管理需求,各类 系统管理 程序也在不断改进。本课题所设计的 停车场管理系统 , 使用 Django 框架 , Python语言 进行开发,它的优点代

    2024年02月10日
    浏览(40)
  • 停车场管理系统文件录入(C++版)

    ❤️作者主页:微凉秋意 ✅作者简介:后端领域优质创作者🏆,CSDN内容合伙人🏆,阿里云专家博主🏆 之前写的停车场管理系统或者是通讯录管理系统都没有使用 文件 录入、保存数据,今天带来一个文件录入信息的C++版停车场管理系统。代码部分都会有详细注释,稍加思

    2024年02月03日
    浏览(39)
  • Python 实验报告,实现停车场收费管理系统

    3.某小型收费停车场有50个车位,有一个入口与一个出口,满1小时收费1元,不足1小时不收费,10元封顶,超过1天罚款200元。编写程序实现停车场出入口管理。 要求: (1)定义出入口类,将车位总数与目前停在停车场的车辆信息(每辆车包括车牌和入场时间)定义为类属性;

    2024年02月12日
    浏览(40)
  • 基于Web的停车场管理系统(Java)

    目录 一、系统介绍 1.开发的环境 2.本系统实现的功能 3.数据库用到的表 4.工程截图 二、系统展示 1、登录页面  2、首页 3、系统信息管理模块   4、车位信息管理模块  5、IC卡信息管理模块 ​编辑6、固定车主停车管理模块 7、临时车主停车管理模块 8、系统功能操作模块 三

    2024年02月10日
    浏览(36)
  • JAVA毕业设计119—基于Java+Springboot+vue的智能停车场管理系统(源代码+数据库+9000字论文)

    毕设所有选题: https://blog.csdn.net/2303_76227485/article/details/131104075 本项目前后端不分离 登录、控制台、停车场管理、车牌识别、车辆管理 角色管理、系统菜单、全局配置、停车记录、财务管理 控制台管理、系统日志、账号管理、用户管理、合作单位管理、密码修改、个人信息

    2024年02月03日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包