刷以前的题目,20分的开始
第一题(字符串处理)
Kuchiguse (20)
输在翻译和 C++ 中一个特别好用的 reverse(x.begin(),x.end());
第二题(数学)
Consecutive Factors (20)
第三题(见面礼)
A+B in Hogwarts (20)
这道题没什么难度,就考一个翻译。(不粘代码了,没意义。)
第四题
A+B and C (64bit) (20)
两个64位数相加,两种办法:
第一种,判断是否发生溢出 :
x+ 、y+ 结果为负数,一定为true
x -、y-、x+y>=0 (注意等于一定要有) 结果为 false
x、y 一正一负,直接相加比大小
第二种 数组相加(些许麻烦,不过比较好想到)
第五题
Shuffling Machine (20)
这道题,还是看不懂英文,真是硬伤。翻译过来就懂了。
很简单,其实用结构体更好一些。考的是数据结构感觉跟算法没什么关系。用两个数组来存改变前的和已经改变的。写了一个方法来简单点的初始化,不然真的很恶心。没什么说的。
#include
using namespace std;
string a[100];
string La[100];//用来保存仍未移动的
void Set(char c,int st)
{
for(int i =1 ;i<14;i++)
{
La[st]=a[st]=c;
if(i<10)
La[st]=a[st]+=i+'0';
else
{
La[st]=a[st]+='1';
La[st]=a[st]+=i%10+'0';
}
a[st++];
}
}
int main()
{
Set('S',1);
Set('H',14);
Set('C',27);
Set('D',40);
La[53] = a[53] = "J1";La[54] = a[54] = "J2";
int re;
int arr[100];//洗牌规则
cin>>re;
for(int i = 1;i<55;i++)
{
cin>>arr[i];
}
for(int i = 0 ;i<re;i++)
{
for(int j = 1;j<55;j++)
{
int x = arr[j];
a[x] = La[j];
}
for(int j=1;j<55;j++)
La[j] = a[j];
}
for(int i=1;i<55;i++)
if(i==1)
cout<<La[i];
else
cout<<" "<<La[i];
}
第六题
Be Unique (20)
过于简单。在碰见直接找答案,没意思这个题。
#include
using namespace std;
int main()
{
int n;
int a[100010];//用来存储出现的顺序
int b[100010]={
0};//用来存储出现次数
cin>>n;
for(int i = 0;i<n;i++)
{
scanf("%d",&a[i]);
b[a[i]]++;
}
int i;
for(i = 0;i<n;i++)
{
if(b[a[i]]==1)
{
printf("%d",a[i]);
break;
}
}
if(i==n)
printf("None");
}
Public Bike Management (30)
30分的题,难度还是在的,用了一个小时多吧。
单源最短路径,DFS,剪枝,回溯。(其实没那么难,不剪枝不知道能不能过)
难点:你需要记录,你需要多少车辆和你最后你需要带回多少车辆。
到了一个点,分两种情况:
1、当前点的车辆大于等于一半,那么从这个点中拿走多余的车,自己装着。
2、当前点的车辆小于一半,检查自己手上的车是否够补,优先用自己手上的车来补上,如果不够,那么讲不够的车的数量记录下来,作为需要从总部拿的车辆。
到了故障点一样的操作,不过操作完需要记录,当前拥有的和需要的,作为最后的答案。
用一个Min数组来剪枝。
(有什么迷的地方可以评论下咱们讨论讨论(。・∀・)ノ,嘿嘿嘿)
代码如下:
#include
using namespace std;
string res; //最终结果
int Min[502]={
0}; //到达距离的最小长度
int Map[502][502]; //地图
int St[502]; //初始车数量
int n; //n个站点
int Cmax; //站点最大存储量
int pb; //问题站点
int Nway; //道路
int Ha = 0,Ne = 9999;//有的、当前需要的
void dfs(string way,int con[502],int time,int now,int bike,int sta,int have,int need)
// 路线,状态,走到当前点走了几步,现在位置,一共多少辆车,多少个站 ,当前有多少车,当前需要多少车
{
if(Min[now] < time&&Min[now]!=0) //当前费用大于以前走过的,说明当前道路不是最好的
return ;
if(now == pb&&((Min[pb]>time||Min[pb]==0)||(Min[pb]==time&&(Ne==9999||Ne>need))))
//判断条件 自己感悟吧
{
Ne = need;
Ha = have;
Min[pb] = time;
res = way;
return;
}
if(Min[now] == 0)
Min[now] = time;
char tmp;
for(int i=1;i<=n;i++)
{
if(i==now||con[i] == 1||Map[now][i] == 0)
continue;
tmp = i+'0';
//回溯
con[i] = 1;
if(St[i]+have>=Cmax/2) //如果说现在拿着的可以补上
dfs(way+"->"+tmp,con,time+Map[now][i],i,bike+St[i],sta+1,have+St[i]-Cmax/2,need);
else //补不上
dfs(way+"->"+tmp,con,time+Map[now][i],i,bike+St[i],sta+1,0,need+Cmax/2-have-St[i]);
con[i] = 0;
}
}
int main()
{
cin>>Cmax>>n>>pb>>Nway;
for(int i=1;i<=n;i++)
cin>>St[i];
for(int i=1;i<Nway+1;i++)
{
int x,y,w;
scanf("%d %d %d",&x,&y,&w);
Map[x][y] = Map[y][x] = w;
}
int con[502] = {
1};
dfs("0",con,0,0,0,0,0,0);
cout<<Ne<<" ";
cout<<res<<" ";
cout<<Ha;
}
The Largest Generation (25)
第一天写了点20的题,回忆回忆感觉。第二天低产了。第三天这是一个25分的题。这给一个类似于树的,挺简单的。遇见了一个问题。
数组初始化问题(有可能很简单但是的确出问题了)。
我发现,在我没有写这clear函数之前,我的gen[]数组是默认为0的。但是在我写之后我就必须得加上 gen[105] = {0,1}这个初始化操作。
从此中得到的经验:用之前还是别省懒事,一定要初始化!!!
继续改,继续改。
分级别的时候一定是 i,j<=n 小于n 就会结果不对哦~~~
(哈哈哈终于找到为什么错了,开心,恰饭恰饭)
#include
using namespace std;
typedef struct{
int child[105];//孩子
int cnum;//孩子的数量
int level;
int parent;
}Node;
Node a[105];//用来存储家庭
void clear()
{
for(int i =0;i<105;i++)
{
a[i].cnum = 0;
if(i!=1)
a[i].level = 0;
else
a[i].level = 1;
a[i].parent = 0;
}
}
int main()
{
int gen[105]={
0,1};//第i代有多少人
int n;//多少人
int cn;//多少人有后代
clear();
cin>>n>>cn;
for(int i = 0 ;i<cn;i++)
{
int num;//当前的人
int cou;//当前人的后代
cin>>num>>cou;
a[num].cnum = cou;
if(a[num].parent!=0&&a[a[num].parent].level!=0&&a[num].level==0)
//如果说找到过父节点 父节点有level 这个节点没有level
{
a[num].level = a[a[num].parent].level+1;
gen[a[num].level]++;
}
for(int j = 0;j<cou;j++)
{
int x;
cin>>x;
a[x].parent = num;
if(a[a[x].parent].level!=0&&a[x].level==0)
{
a[x].level = a[a[x].parent].level+1;
gen[a[x].level]++;
}
}
}
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
if(a[j].level==0&&a[a[j].parent].level!=0&&a[j].parent!=0)
{
a[j].level = a[a[j].parent].level+1;
gen[a[j].level]++;
}
}
}
int max = 1;
int sum = 0;
for(int i = 1;i<=cn;i++)
{
sum+=gen[i];
if(gen[max]<=gen[i])
max = i;
}
cout<<gen[max]<<" "<<max;
}
心态有些许崩,两天两道题,愣是不对。
所以写了一个20分的玩了玩,emmm,20的真是舒服
Hello World for U (20)
(答案不粘贴了,过于简单)就当练手了,加油~~。
状态不是特别好,找了一个25分的题写了写,第一个没写出来,就去找了另一个,还是没写出来,不过后来看了看大神的代码,若有所悟。
题目:
Highest Price in Supply Chain (25)
这个是一个树的深度问题,一开始能看懂题目,但是树学的不怎么地,所以不会做。最后看了看大佬写的,非常简洁明了,于是打开DevC自己又写了一遍。
代码:
#include
using namespace std;
int n;
int maxDep = 0;
int maxNum = 0;
int tmp;
int root;
vector<int> v[100050];
void DFS(int index,int dep)
{
if(v[index].size() == 0)
{
if(maxDep == dep)
{
maxNum++;
}
else if(maxDep < dep)
{
maxDep = dep;
maxNum = 1;
}
}
for(int i =0;i<v[index].size();i++)
DFS(v[index][i],dep+1);
}
int main()
{
double e,r;
cin>>n>>e>>r;
for(int i =0;i<n;i++)
{
cin>>tmp;
if(tmp == -1)
root = i;
else
v[tmp].push_back(i);
}
DFS(root,0);
printf("%.2lf %d",e*pow(1+r/100,maxDep),maxNum);
}
心得:
个人感觉,这个代码中的树的高度以及存储方法,很是舒服。用Vector来存储树,说实话以前我还真没有想过这种数据结构存储。
个人认为代码可以复用,理解下来背下来~~。
今天继续写,虽然每天写的不多,但希望自己可以坚持下去!!!!
Deduplication on a Linked List (25)
这是一个25分题中比较简单的一个吧,但是就是敲代码麻烦。做了将近40分钟。速度挺慢相对于这道题。
代码:
#include
using namespace std;
typedef struct {
int Num;
int next;
}Node;
int star;
int n;
int ex[100050]={
0};//用来判断是否存在
Node arr[100050];//用来存储
int Last= -1;//上一个在这个队列中的下标
int start= -1;//新创建的队列的头部。
int End = -1;//尾部
int main()
{
cin>>star>>n;
int point = 0;
for(int i =0;i<n;i++)
{
int num,tmp,next;
scanf("%d %d %d",&tmp,&num,&next);
arr[tmp].next = next;
arr[tmp].Num = num;
}
int num = 0;
while(1)
{
if(ex[abs(arr[star].Num)]==0)
{
ex[abs(arr[star].Num)] = 1;
if(num==0)
{
printf("%05d %d",star,arr[star].Num);
num++;
}
else
{
printf(" %05d\n%05d %d",star,star,arr[star].Num);
}
Last = star;
if(arr[star].next == -1)
{
printf(" -1\n");
break;
}
else
star = arr[star].next;
}
else
{
if(start == -1)
{
start = star;
End = star;
arr[Last].next = arr[star].next;
arr[start].next = -1;
}
else
{
arr[End].next = star;
End = star;
arr[Last].next = arr[End].next;
arr[End].next = -1;
}
star = arr[Last].next;
}
if(star == -1)
{
printf(" -1\n");
break;
}
}
while(1)
{
if(arr[start].next != -1)
printf("%05d %d %05d\n",start,arr[start].Num,arr[start].next);
else
printf("%05d %d -1",start,arr[start].Num);
start = arr[start].next;
if(start == -1)
break;
}
}
总结:
主要考察数据结构的一道题,因为N小,可以用数组来写,如果大的话,有可能就需要容器之类的结构来写了,较为简单,队列应该会更简单吧~~。
Wow,做到了一个特别舒适的题目,树的层序遍历,搜索二叉树。
Build A Binary Search Tree (30)
刚开始的确不会,连树的层序遍历都忘了,然后打开了百度,输入了题目,出来了大佬的答案,看完之后,惊了,真的精彩!!!
代码:
#include
using namespace std;
typedef struct {
int l,r,v;
}Node;
Node Tree[1005];
vector<int> p;
int cnt = 0;
void inOder(int i)
// !!!!!!好方法!!!!!!!!!好方法!!!!!!!!!好方法!!!!!!!!
{
if(Tree[i].l!=-1)
inOder(Tree[i].l);
Tree[i].v = p[cnt++];
if(Tree[i].r!=-1)
inOder(Tree[i].r);
}
int main()
{
int n;
cin>>n;
for(int i = 0;i<n;i++)
{
cin>>Tree[i].l>>Tree[i].r;
}
for(int i =0;i<n;i++)
{
int tmp;
cin>>tmp;
p.push_back(tmp);
}
sort(p.begin(),p.end());
inOder(0);
queue<Node> q;
q.push(Tree[0]);
int flag = 1;
while(!q.empty())
{
Node tmp = q.front();
q.pop();
if(flag-- == 1)
printf("%d",tmp.v);
else
printf(" %d",tmp.v);
if(tmp.l != -1)
q.push(Tree[tmp.l]);
if(tmp.r != -1)
q.push(Tree[tmp.r]);
}
}
主要部分:
void inOder(int i)
{
if(Tree[i].l!=-1)
inOder(Tree[i].l);
Tree[i].v = p[cnt++];
if(Tree[i].r!=-1)
inOder(Tree[i].r);
}
/*
这个函数解决这个问题真的绝了,真的太精彩了.
找到树的最左边,那么这就是当前树中最小的数,然后来记录,再向右找。
怎么说呢,这个大佬感觉真的把树的遍历学透了,强!!!!!!
真的帅。
*/
树的层序遍历:
忘了,所以巩固巩固,回忆回忆
queue<Node> q;
q.push(Tree[0]);
int flag = 1;
while(!q.empty())
{
Node tmp = q.front();
q.pop();
if(flag-- == 1)
printf("%d",tmp.v);
else
printf(" %d",tmp.v);
if(tmp.l != -1)
q.push(Tree[tmp.l]);
if(tmp.r != -1)
q.push(Tree[tmp.r]);
}
总结:
树的层序遍历(队列实现),二叉搜索数的性质(最左边的最小,左小,右大)。(ps:深切的感觉到了算法的魅力)
废话不多说,继续来做题。
Prime Factors (25)
这是一道找素数题,需要对操作的数字进行优化。
一开始用很是暴力的方法解题:
代码如下:
#include
using namespace std;
bool is_prime(long long x)
{
long long tmp = sqrt(x);
for(int i = 3;i<=sqrt(x);i++)
{
if(x%i==0)
return false;
}
return true;
}
int main()
{
long long n;
cin>>n;
cout<<n<<"=";
if(n == 1)
{
cout<<"1";
return 0;
}
long long tmp = n;
for(int i =2;i<=tmp;i++)
{
int k = 0;//用来记录除以了多少次
if(is_prime(i))
{
while(n%i==0)
{
k++;
n/=i;
}
}
if(k>1)
{
cout<<i<<"^"<<k;
}
else if(k==1)
{
cout<<i;
}
if(n!=1&&k>=1)
printf("*");
else if(n==1)
break;
}
return 0;
}
但是,提交上去以后,发现Wa了,原因是超时。于是我想了想怎么优化。
就出现了下面部分的改动:
long long tmp = sqrt(n);
//循环开始
......
//中间代码省略
....
//循环结束以后
if(n!=1)
printf("%d",n);
这样我的代码就AC了。
然后就想看看大家是怎么解题的,就看到了一个思路:
就是将小于50000的质数,全部先用数组记录下来。
如下:
vector<int> prime(50000, 1);
for(int i = 2; i * i < 50000; i++)
for(int j = 2; j * i < 50000; j++)
prime[j * i] = 0;
用了Vector容器来解决这个问题。但是由于我不熟悉Vector 于是我用数组又写了一个。
int prime[50005] ={
1,0,0};
for(int i = 2; i * i < 50000; i++)
for(int j = 2; j * i < 50000; j++)
prime[j * i] = 0;
//判断条件变成了
if(prime[i]==0)
{
......
}
结果是真的快,嘿嘿嘿,高兴。
总结:
所以,在遇到需要质数的情况下,有两种办法:
若数字不过于大,推荐使用先初始化的方法。
若数字范围不好确定,最好自己手写一个is_prime()函数。
Vector容器可以定义的时候初始化:
vector
(写的时候才知道prime是质数的意思 (///∀///) 。)
话不多说,上今天的题目。
Total Sales of Supply Chain (25)
舒服,这个题跟10号的题目差不多,wow,还能记起来怎么写,自己写了一遍,相当流畅,就是出现了编译错误。
**考点:**树的高度问题。
代码:
#include
using namespace std;
vector<long long> vv[100010];
long long star[100010] ={
0};
long long cou[100010] = {
0};
double p,r;
double sum = 0;
int Be;
void Lv(int now,int lev)
{
if(cou[now]!=0)
{
double s = p;
while(lev--)
{
s = s*(1.0+r/100);
}
sum+=s*cou[now];
return ;
}
for(std::size_t i=0;i<vv[now].size();i++)
{
Lv(vv[now][i],lev+1);
}
}
int main()
{
long long n;
cin>>n;
cin>>p>>r;
for(int i = 0;i<n;i++)
{
int tmp;
cin>>tmp;
for(int j=0;j<tmp;j++)
{
int tp;
cin>>tp;
vv[i].push_back(tp);
star[tp] = 1;
}
if(tmp==0)
{
int tp;
cin>>tp;
cou[i] = tp;
}
}
for(int i =0;i<n;i++)
if(star[i] == 0)
{
Be = i;
break;
}
Lv(Be,0);
printf("%.1lf",sum);
}
遇到的问题:
出现了编译错误,最后调整了一下变量以及函数的名称,例如:level、begin之类的名字,不可以叫,不然的话,会出现编译的问题(当然前提是你用的万能头文件)。
图的广度搜索,跟前两天深度搜索的感觉差不多,于是刚开始用的DFS(没看出来),然后WA了,看了卡大家写的。
代码:
#include
#include
#include
#include
#include
using namespace std;
vector<int>vt[1005];
bool flag[1005];
int n,level;
int MaxForward(int val){
memset(flag,false,sizeof(flag));
queue<int>q;
q.push(val);
flag[val]=true;
int sum=1;
int cntLevel=0;
int start=0;
int end=1;
while(!q.empty()){
val=q.front();
q.pop();
start++;
int size=vt[val].size();
for(int i=0;i<size;i++){
if(flag[vt[val][i]]==false){
q.push(vt[val][i]);
flag[vt[val][i]]=true;
sum++;
}
}
if(start==end){
//计算层数
end=sum;
cntLevel++;
}
if(level==cntLevel){
return sum-1;
}
}
return sum-1;
}
int main(){
scanf("%d%d",&n,&level);
int tmp,val;
for(int i=1;i<=n;i++)
{
scanf("%d",&tmp);
for(int j=0;j<tmp;j++)
{
scanf("%d",&val);
vt[val].push_back(i);
}
}
int k;
scanf("%d",&k);
for(int i=0;i<k;i++)
{
scanf("%d",&val);
val=MaxForward(val);
printf("%d\n",val);
}
return 0;
}
遇到的问题:
就是DFS和BFS,不知道为什么DFS不正确,去发个帖子问问大佬去。其他思路之类的,跟昨天的一样。挺白给的30分。
哈哈哈,AC了,发现哪了错了啊,大家一定要,一定一定要用memset时记得写sizeof(type) 不要忘了,坑死我了。
DFS代码:
个人觉得,效率高,还简单╮(╯▽╰)╭。
#include
using namespace std;
vector<int> vv[100010];
int rem[1010];
int n;
int L;
int cou;
void DFS(int now,int Lv)
{
if(Lv==L)
return ;
for(int i=0;i<vv[now].size();i++)
{
if(rem[vv[now][i]]++==0)
{
cou++;
}
DFS(vv[now][i],Lv+1);
}
}
int main()
{
cin>>n>>L;
for(int i =1;i<=n;i++)
{
int Num;
int tmp;
cin>>Num;
while(Num--)
{
cin>>tmp;
vv[tmp].push_back(i);
}
}
int Num;
cin>>Num;
for(int i =0;i<Num;i++)
{
int tmp;
cin>>tmp;
memset(rem,0, sizeof(int)*1005);
cou = 0;
rem[tmp] = 1;
DFS(tmp,0);
cout<<cou<<endl;
}
}
模拟栈的题目,我用的是数组,难点在于怎么寻找中间数,不过也没那么难,真希望我的秋季赛也能这么简单。
代码:
#include
using namespace std;
int num[100010] = {
0};//记录各个数字一共多少个
int cou = 0;
int main()
{
int n;
cin>>n;
int a[100010];
int point = -1;
for(int i =0;i<n;i++)
{
string tmp;
getchar();
cin>>tmp;
if(tmp == "Pop")
{
if(point==-1)
{
printf("Invalid\n");
continue;
}
num[a[point]]--;
printf("%d\n",a[point--]);
cou--;
}
else if(tmp == "PeekMedian")
{
if(point == -1)
{
printf("Invalid\n");
continue;
}
int sum = 0;
int n = 0;
if(cou==1)
printf("%d\n",a[0]);
else
{
int l = cou;
if(cou%2==1)
l++;
while(sum<l/2)
{
if(sum+num[n] >= l/2)
{
cout<<n<<endl; break;
}
sum+=num[n++];
}
}
}
else
{
int x;
cin>>x;
num[x]++;
a[++point] = x;
cou++;
}
}
}
总结:
提交完代码之后,发现速度挺慢的,于是网上又找了一个代码提交了上去,发现他也不快,这我就放心了,时间复杂度的确挺高,希望在后面写代码的过程中能想到方法改善代码。
Hashing (25)
比较简单的一道题,但是出现了**开放定址法——平方探测(Quadratic Probing)**这个方法,卡在这个名词上了,查了一下过了。
定理
如果使用平方探测,且表的规模是素数,那么当表至少有一半是空的时候,总能插入新的元素。
代码:
#include
using namespace std;
int Re[10010]={
0};
int Po[10010]={
0};
bool is_prim(int x)
{
if(x==1)
return false;
int l = sqrt(x);
for(int i =2;i<=l;i++)
{
if(x%i==0)
return false;
}
return true;
}
int main()
{
int m,n;
int tmp;
cin>>m>>n;
while(!is_prim(m++));
m-=1;
memset(Po,-1,sizeof(int)*10000);
for(int i =0;i<n;i++)
{
cin>>tmp;
for(int j=0;j<m;j++)
{
int mod = (tmp+j*j)%m;
if(Re[mod] == 0)//没有数字
{
Re[mod] = 1;
Po[i] = mod;
break;
}
}
}
for(int i =0;i<n;i++)
{
if(i!=0)
cout<<" ";
if(Po[i] == -1)
printf("-");
else
cout<<Po[i];
}
}
总结:
很简单的一道题,但是需要Hashmap的知识和“平方探测(Quadratic Probing)” 的知识。
写不出来题,头发越来越长,快疯了。/(ㄒoㄒ)/~~
今天舒服了,一遍 AC。但是说实话,30分的题,真的有点难,我写了好几个都无法AC。
Shopping in Mars (25)
题目:
求连续几个数凑成一个数,找到浪费最小的。
代码:
#include
using namespace std;
typedef long long ll;
int n;
ll cou = 0;
int a[100010];
int Min=999;
int Mcou=0;
int rem[100010][2];
int Index = 0;
void DFS(int x,int sum,int star)
{
sum+=a[x];
if(sum >= cou)
{
if(sum-cou<Min)
{
Min = sum-cou;
Mcou=1;
Index = 0;
rem[Index][0] = star;
rem[Index++][1] = x;
}
else if(sum-cou == Min)
{
rem[Index][0] = star;
rem[Index++][1] = x;
Mcou++;
}
// printf("Min = %d,sum = %d\n",Min,sum);
return ;
}
if(x>=n)
return ;
DFS(x+1,sum,star);
}
int main()
{
cin>>n;
cin>>cou;
for(int i =0;i<n;i++)
{
cin>>a[i];
}
for(int i =0;i<n;i++)
DFS(i,0,i);
for(int i =0;i<Index;i++)
{
printf("%d-%d\n",rem[i][0]+1,rem[i][1]+1);
}
}
总结:
搜索就好了,从当前位置向后搜索,记录起始位置和结束位置,一遍AC,舒服。
Speech Patterns (25)
思想不难,但是实现的问题上我用Map出了问题,让我更仔细地了解到了C++中Map的用法,先粘代码,后面总结。
代码如下:
#include
using namespace std;
int main()
{
char c;
string x="";
int Mnum=0; //出现最多的字符串出现次数
map<string,int> m;
while(1)
{
scanf("%c",&c);
if(c=='\n')
break;
if(c>='a'&&c<='z'||c>='A'&&c<='Z'||c>='0'&&c<='9')
{
if(c>='A'&&c<='Z')
x+=c+32;
else
x+=c;
}
else if(x!="")
{
if(m.count(x)==0)
m[x] = 0;
m[x]++;
// cout<
if(m[x]>Mnum)
{
Mnum = m[x];
}
x="";
}
}
map<string,int>::iterator it = m.begin();
while(it != m.end())
{
if(it->second == Mnum)
{
cout<<it->first<<" ";break;
}
it++;
}
cout<<Mnum;
}
关于Map的:
这道题简单,但是涨姿势了。
三天没有更新,但是三天一直在写蓝桥杯,啊,真的难啊,快难哭了/(ㄒoㄒ)/~~。