蓝桥真题


有奖问答
这种选择导致分支可以使用递归

我个人觉得洛谷的答案错了,如果按能得到洛谷答案的代码,改成求30题对30道,最多对30道的话,得到的是0,应该把限制条件改为能计算答对10道题的方案,因为最多十道题不是不能达到10道题

DFS
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
int ans=0;
void work(int t,int m)//已答完的题和已经拿到的分数
{
	
	if(m==7&&t==30) ans++;//求的是结束后的积分,所以==30,中途结束的可认为是自那之后一直没答对
	if(t==31) return;
	if(m==11) return;
	work(t+1,m+1);
	work(t+1,0);
}
int main() {
	work(0,0);
	cout<<ans;
	return 0;
}
DP
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
int dp[40][40];

int main() {
	dp[0][0]=1;
	for(int i=1;i<=30;i++)
	{
		for(int j=0;j<=10;j++)
		{
			if(j<=9) dp[i][j+1]+=dp[i-1][j];
			dp[i][0]+=dp[i-1][j];
		}
	}
	
	cout<<dp[30][7];
	return 0;
}
--------------------------------------------------------------------------------------------------

平方差
推柿子,得到 x=(y−z)×(y+z),可知 x 满足可以拆成 2 个奇偶性相同的数的乘积。

如果是奇数,直接拆成 1 和它本身即可。

如果是偶数,因为要拆成 2 个偶数,所以应是 4 的倍数,此时一种拆分为拆成 2 和 x 除以 2。

至此,答案为 l 到 r 中 奇数4 的倍数 的个数。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int f(int x) {//小于等于x的奇数个数 
	if (!x) return 0;
	return (x + 1) / 2;
}
int g(int x) {//小于等于x的4的倍数个数 
	return x / 4;
}
int main() {
	int l, r; cin >> l >> r;
	cout << f(r) - f(l - 1) + g(r) - g(l - 1);
	return 0;
}
--------------------------------------------------------------------------------------------------

更小的数
难得一遍过

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;

string s;
LL ans;
int main() {
	cin>>s;
	for(int i=0;i<s.length()-1;i++)
	{
		for(int j=i+1;j<=s.length()-1;j++)
		{
			for(int k=1;k<=(j-i+1)/2;k++)
			{
				if(s[i+k-1]-'0'>s[j-k+1]-'0')
				{
					ans++;
					break;//i-j区间已经查完,更小的子区间以后会查到,要break防止重复
					/*cout<<s[i+k-1]<<" "<<s[j-k+1]<<" "<<i<<" "<<j<<endl;*/
				}
				else if(s[i+k-1]-'0'<s[j-k+1]-'0') break;
			}
		}
	}
	cout<<ans;
	return 0;
}
--------------------------------------------------------------------------------------------------

五子棋

做了一天,感觉自己真不是搞算法的料
一开始把题目看错了,看成了不同的落子顺序也算不同的结局,一顿饭吃完还没跑完答案
其实是不算顺序,只看最终棋局
题目是DFS
每次下一个子,可以是 1 或者是 2 ,maps【i】【j】= 1 或者 2 .
先看下 1 的情况 ,maps【i】【j】= 1 , 然后另一个玩家落子 ,dfs ( i , j + 1 )
然后是 2 的情况 ,maps【i】【j】= 2 , 然后另一个玩家落子 ,dfs ( i , j + 1 ).

下到最后肯定会填满,满了之后检查 (check) 棋局是否满足要求,即没有 横 竖 斜 的 五子连珠
满足的话就 ans++;
之后return , 考虑 上一步棋的另一种情况

如果这步棋 1 , 2 都考虑了,那就这步棋撤回,maps【i】【j】= 0,
然后return ,考虑 上一步棋的另一种情况

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
LL ans,maps[6][6];
bool check()
{
	int c1=0,c2=0;
	for(int i=1;i<=5;i++)
	{
		for(int j=1;j<=5;j++)
		{
			if(maps[i][j]==1) c1++;
			if(maps[i][j]==2) c2++;
		}
	}
	if(c1-c2!=1) return true; //要符合条件的话,先手的13棋,后手12棋,先手-后手=1
	
	for(int i=1;i<=5;i++)
	{
		bool t=true;//要注意检查每行是否有连珠,不能放外面初始化,不然一行没有连珠的话,下面可能连珠的当成没有连珠了,下面同理,因为这个卡了好久
		for(int j=1;j<=5;j++)
		{
			if(maps[j][i]!=maps[1][i]) t=false;
			
		}
		if(t) return true;
	}
	
	for(int i=1;i<=5;i++)
	{
		bool t=true;
		for(int j=1;j<=5;j++)
		{
			if(maps[i][j]!=maps[i][1]) t=false;
		
		}
		if(t) return true;
	}
	
	
	bool t=true;
	for(int k=1;k<=5;k++)
	{
		if(maps[k][6-k]!=maps[1][5]) t=false;
	}
	if(t) return true;
	
	t=true;
	for(int k=1;k<=5;k++)
	{
		if(maps[k][k]!=maps[1][1]) t=false;
	}
	if(t) return true;


	return false;
}
void dfs(int i,int j)
{
	if(j>=6)
	{
		i++,j=1;
	}
	if(i>=6)
	{
		if(!check()) ans++;
		return;
	}
	maps[i][j]=1;
	dfs(i,j+1);
	maps[i][j]=2;
	dfs(i,j+1);
	maps[i][j]=0;
	return;
}

int main() {
	dfs(1,1);
	cout<<ans;
	return 0;
}
--------------------------------------------------------------------------------------------------

训练士兵
挺简单的一道题,每次检查所有士兵的训练费用是否小于组团训练费用,小的话就全体单独训练,大于就组团训练

我的方法是每次用 当前最小的次数 - 已经训练的次数 ,但之前一直错误地把 已经训练的次数 当成 每次训练的次数的累加 了

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
LL n,S,ans,ttc,ttt;

struct P{
	LL cost=0,time=0;
	P()=default;
	P(LL c,LL t):cost(c),time(t){};
	bool operator<(const P & b)const{
		return time>b.time;
	}
};

priority_queue<P> p;

int main() {
	cin>>n>>S;
	for(int i=1;i<=n;i++)
	{
		LL a,b;
		cin>>a>>b;
		ttc+=a;
		p.push(P(a,b));
	}
	while(!p.empty())
	{
		LL mc=0,mt=p.top().time;
		if(ttc<=S)
		{
			ans+=ttc*(mt-ttt);
		}
		else
		{
			ans+=S*(mt-ttt);	
		}
		while(!p.empty()&&p.top().time==mt)
		{
			mc+=p.top().cost;
			p.pop();
		}
		ttc-=mc;
		ttt=mt;//害人精,找了我一天
	}
	cout<<ans<<endl;
	return 0;
}
--------------------------------------------------------------------------------------------------

成绩统计

数学检测题,一开始用的办法是:
先检测 k 个是否符合条件
记当前的序号为 i
然后从 k+1 开始 , 每次将前 i - 1 个数按减去平均数并 abs 后的大小(即波动程度)排序 , 将差值最大的 i - 1 与 i 比较 , 若是 i 的波动更小,则替换掉 i - 1 否则往后推
但是这样做会 TLE

所以应该用复杂度更小的二分查找
方差 = 每个数^2 / n - 平均数^2.

每次二分后要在区间内排序,之后遍历每个 k 长度的区间计算方差 , 取最小 ,小则 r = mid - 1 , 大于等于则 l = mid + 1
n * log n * k 还是不够,而遍历 k 长度区间是求 和 与 平方和 , 用前缀和

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
LL a[100010],tot[100010],pown[100010],b[100010],n,k,t;

bool check(int x)
{
	for(int i=1;i<=x;i++) b[i]=a[i];
	sort(b+1,b+1+x);
	for(int i=1;i<=x;i++)
	{
		tot[i]=tot[i-1]+b[i];
		pown[i]=pown[i-1]+b[i]*b[i];
	}
	double ans=1e300;
	for(int i=k;i<=x;i++)
	{
        //从每个 i 开始检查,一开始写了 [ x ]
		ans=min(ans,((1.0*pown[i]-1.0*pown[i-k])/k)-( (1.0*tot[i]-1.0*tot[i-k]) / k )*( (1.0*tot[i]-1.0*tot[i-k]) / k ));
	}
	return ans<t;
}

int main() {
	cin>>n>>k>>t;
	for(int i=1;i<=n;i++) cin>>a[i];

	int l=k,r=n,ans=-1;
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(check(mid))
		{
			ans=mid;
			r=mid-1;
		}
		else l=mid+1;
	}
	
	cout<<ans;
	
	return 0;
}
--------------------------------------------------------------------------------------------------

积木

dp题
当前状态可以按如下方式摆放:

这个摆放可一直延伸到 F(0) (L型方块存在时,由于可以转动放置,方案数*2),故可得到如下推导:

然后手动dp即可
不LL,一场空

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e7+10;
LL n,mod=1000000007,ans,dp[N];
int main() {
	cin>>n;
	dp[1]=1,dp[2]=2,dp[3]=5;
	for(int i=4;i<=n;i++)
	{
		dp[i]=(2*dp[i-1]%mod+dp[i-3]%mod)%mod;
	}
	cout<<dp[n]<<endl;
	return 0;
}

--------------------------------------------------------------------------------------------------

数位反转
反转操作:

int re(int a)
{
	int res=0;
	while(a)
	{    //想象一下栈的进出,类似这种感觉
		res=(res<<1)+(a&1);
		a>>=1;
	}
	return res;
}

如果 dp 的是数的值的话,就相当于累加,可能会爆
选择 dp 反转后与原来的差值 , 最后选择最大的和最初的累加 sum 相加
当前有 转 or 不转 ,当前最大值取决于 前面转不转
如果当前 转 (1) , 则前面 不转(0) ———— i-1 的反转次数 j-1 , 转(1)———— i-1 的反转次数 j 不变
如果当前 不转(0) , 则前面 不转(0) ———— i-1 的反转次数 j , 转(1)———— i-1 的反转次数 j 不变

代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
int n,m;
LL dp[1010][1010][2],t,sum,cha,d[1010];
int re(int a)
{
	int res=0;
	while(a)
	{
		res=(res<<1)+(a&1);
		a>>=1;
	}
	return res;
}

int main() {
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>t;
		sum+=t;
		d[i]=re(t)-t;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j][1]);
			dp[i][j][1]=max(dp[i-1][j-1][0],dp[i-1][j][1])+d[i];
		}
	}
	for(int i=1;i<=m;i++) cha=max(cha,max(dp[n][i][0],dp[n][i][1]));
    //因为不一定反转后会变大,所以要遍历,看哪个最大
	cout<<sum+cha;
	return 0;
}

--------------------------------------------------------------------------------------------------

买瓜

正常思路:
每个瓜 买 | 买一半 | 买整个
买一半 ——> cnt+1
三种状态 dfs 一遍
sum == m ,ans = min ( ans , cnt )
return
如果 now == n+1 , return

优化:
当 cnt > ans ,return 剪枝
当 sum > m ,return 剪枝

但是还是 3^n 的复杂度

重点:
折半搜索
将 n 拆成两半 ,每次 dfs 其中一个
dfs 前一半时 , 到最后将 sum 与对应的 cnt 记录
dfs 后一半时 , 到最后将 sum 与前一半最后的 sum 相加 , 如果存在对应的 cnt ,则 当前cnt 与对应的 cnt 相加后,与 ans 比较 , 更新答案

代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
LL n,m,ans=LLONG_MAX,a[40],N;
unordered_map <LL,LL> q;//记录折半后,一半点的 sum -- cnt 对应关系

//快读压下时间
LL read()
{
	LL res=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!=EOF) ch=getchar();
	while(isdigit(ch))
	{
		res=(res<<3)+(res<<1)+ch-'0';
		ch=getchar();
	}
	return res;
}

void dfs1(int now,LL sum,LL cnt)
{
	if(cnt>ans||sum>m) return;
    //当前 劈瓜次数 大于 记录最小值 ,剪枝
    //当前 买瓜总重量 大于 需要值 ,剪枝
	if(sum==m)
	{
		ans=min(ans,cnt);//刚好买够,更新答案
		return;
	}

	if(now==N+1)
	{
        //前提是 买瓜总重量 小于等于 需要值 , 才能记录,不然后面也没得买
		if(sum<=m)
		{
            //将当前 买瓜重量 需要的 劈瓜次数 记录为最少那个
			if(q.count(sum))
			{
				q[sum]=min(q[sum],cnt);
			}
			else q[sum]=cnt;
		}
		return;
	}
	dfs1(now+1,sum,cnt);//不买
	dfs1(now+1,sum+a[now],cnt+1);//劈
	dfs1(now+1,sum+(a[now]<<1),cnt);//买整个
}

void dfs2(int now,LL sum,LL cnt)
{
	if(cnt>ans||sum>m) return;
	if(sum==m)
	{
		ans=min(ans,cnt);
		return;
	}
	if(now==n+1)
	{
        //如果后半段的 sum 存在一个 前半段记录的 sum 与之相加 == m ,则可以刚好买够瓜
		if(q.count(m-sum))
		{
			ans=min(ans,q[m-sum]+cnt);
		}
		return;
	}
	dfs2(now+1,sum,cnt);
	dfs2(now+1,sum+a[now],cnt+1);
	dfs2(now+1,sum+(a[now]<<1),cnt);
}

int main() {
	n=read(),m=read();
	for(int i=1;i<=n;i++) a[i]=read();
    //排序,小到大 或者 大到小,看评论好像 小到大 蓝桥官网过不了,大到小洛谷过不了
	sort(a+1,a+1+n);
	m<<=1;
	N=n>>1;
    //搜前半段
	dfs1(1,0,0);
    //搜后半段
	dfs2(N+1,0,0);
    //printf 更快,再贪一点 
	printf("%lld",(ans==LLONG_MAX)? -1:ans);

	return 0;
}
--------------------------------------------------------------------------------------------------

左孩子,右兄弟

意思是当前节点的 兄弟节点 变为 右子节点(成一条),子节点 变成 左节点 (一个,这个节点重复以上操作)

由于 根节点 1 的兄弟节点数量是固定的 , 所以要找出 子节点中完成操作后长度最大 的子节点放在最后 , 决定深搜

不知道哪个子节点的子节点数量最大,要逐一dfs,找到最大得到,决定dp

每个节点的所有子节点数量为 该点的 size ,
最大的 子节点的子节点的数量为 该节点的 num
dp [ now ] == size + num ;

看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+10;
LL n,head[N],cnt,dp[N],size[N];
LL read()
{
	LL res=0;
	char ch=getchar();
	while(!isdigit(ch)&&ch!=EOF) ch=getchar();
	while(isdigit(ch))
	{
		res=(res<<3)+(res<<1)+ch-'0';
		ch=getchar();
	}
	return res;
}
struct Edge{
	int nxt,to,size;
}edge[N<<1];
void add(int from,int to)
{
	edge[++cnt].to=to;
	edge[cnt].nxt=head[from];
	head[from]=cnt;
	size[from]++;
}

void dfs(int now)
{
	for(int i=head[now];i;i=edge[i].nxt)
	{
		int to=edge[i].to;
		dfs(to);
		dp[now]=max(dp[now],dp[to]);
	}
	dp[now]+=size[now];
}

int main() {
	n=read();
	for(int i=2;i<=n;i++)
	{
		int from=read();
		add(from,i);
	}
	dfs(1);
	cout<<dp[1];
	return 0;
}

--------------------------------------------------------------------------------------------------

波动数列
设 p == a / -b ,

所以就要找出累加到最后,(得数 mod n) == (s mod n) 的情况的总数
而 dp 的不是当前的数,而是累加的数,所以不是 当前 的数 - /+ p ,


那如何 dp 总和?
看上图,总和即整个图形的面积
但是从左往右顺序 dp 的话,很难统计前面的总和,因为不知道前面具体是怎么选的,

但是从右往左 dp 的话,可以发现每次选择都会使总和加上 p*右边的长度
而当我们以右端为起点时,右边的长度就等于 i 了

代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const LL mod=1e8+7;
LL n,s,a,b,dp[1010][1010],ans;

LL read()
{
	LL res=0;
	char ch=getchar();
	while(!isdigit(ch)&ch!=EOF) ch=getchar();
	while(isdigit(ch))
	{
		res=(res<<3)+(res<<1)+ch-'0';
		ch=getchar();
	}
	return res;
}


int main() {
	n=read(),s=read(),a=read(),b=read();
	s=(s%n+n)%n;
	dp[0][0]=1;
	for(int i=1;i<n;i++)
	{
		for(int p=0;p<=n;p++)
		{
			dp[i][p]=(dp[i-1][((p-i*a)%n+n)%n])%mod+(dp[i-1][((p+i*b)%n+n)%n])%mod;
		}
	}
	ans=dp[n-1][s]%mod;
	cout<<ans;
	return 0;
}
--------------------------------------------------------------------------------------------------

接龙数列

最少删除次数,即最后接龙数列的最大长度是多少

求最大长度——>dp
正常思路是:
d p [ i ] = m a x ( d p [ i - ( 前面可接龙的数的引索 ) ] + 1 , d p [ i ] )
初始化 :每个数接龙数列长度至少为 1 ,

O( n^2 ) 数据 1e5 会超时

就得优化

在往前找可接龙的数的时候,会遍历很多不可接龙的数
而 每个数的开头 ( head ) 和结尾( tail ) 都是 0 ~ 9
就可以直接 去找 tail == head 的数
将 d p 开一个第二维来找 tail == head

代码
```plaintext
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+3;
int n,dp[N][10];
string t;

int main() {
	cin>>n;
	if(n==1)
	{
		cout<<0<<endl;
		return 0;
	}
	for(int i=1;i<=n;i++)
	{
		cin>>t;
		int s=t[0]-'0',e=t[t.length()-1]-'0';
		for(int j=0;j<=9;j++)
		{
			dp[i][j]=max(dp[i][j],dp[i-1][j]);
			if(s==j) dp[i][e]=max(dp[i-1][s]+1,dp[i-1][e]);
		}
	}
	int ans=0;
	for(int i=0;i<=9;i++)
	{
		ans=max(dp[n][i],ans);
	}
	cout<<n-ans;;
	return 0;
}

也可以这样考虑:
每次都是要找 (前面 tail) == (当前 head) 的数的最大长度 +1
那不就是 当前 head 的最大长度 +1 ?
处理完之后 , 当前 tail 的最大长度 不就是 max( tail 当前最长 ,当前 head 最大长度 +1 )?

代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+3;
int n,ans;
unordered_map < int , int > dp;


void sovle()
{
	cin>>n;
	vector < string > a(n);
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		int s=a[i][0],e=a[i].back();
		int curlen=dp[s]+1;
		dp[e]=max(dp[e],curlen);
		ans=max(dp[e],ans);
	}
	cout<<n - ans<<endl;
}

int main() 
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	sovle();
	
	return 0;
}	
--------------------------------------------------------------------------------------------------

对局匹配

为什么贪心和DP会出现在同一题里啊

贪心:
按顺序找每个相邻的对

选择人数多的那个保留,另一个不要了,

因为是从左往右顺次查找

所以右边那个要保留下最佳答案来给下一个数进行选择,

所以就类似DP了?

要保留最佳答案的话

就是每次当前相比左边的大的话,就说明左边不要了,要在总数里扣除左边,正好右边比左边大,就用右边减去左边

问了一下DS,说是 i 只依赖于 i-k ,而 i-k 是已经进行更新后的最佳答案

所以应该把选择后的最佳答案放在 i ,所以要把 更新 这个操作放在 i
所以 要选择在 i 体现舍去,
左边大,就在 i 舍去, 重置为0
右边大,就在 i 舍去, i 的人数 - i-k 的人数

#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+10;
LL n,ans,a[N],dp[N][2],k,x,h[N],cnt;

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n>>k;
	
	for(int i=1;i<=n;i++)
	{
		cin>>x;
		a[x]++;
		if(a[x]==1) h[++cnt]=x;
	}
	if(k==0)
	{
		cout<<cnt;
		return 0;
	}
	sort(h+1,h+1+cnt);
	for(int I=1;I<=cnt;I++)
	{
		int i=h[I];
		if(i-k>=0)
		{
			if(a[i-k]<a[i])
			{
				a[i]=a[i]-a[i-k];
			}
			else
			{
				a[i]=0;
			}
		}
	}
	for(int I=1;I<=cnt;I++)
	{
		int i=h[I];
		ans+=a[i];
	}
	cout<<ans;
	return 0;
}

--------------------------------------------------------------------------------------------------

糖果(状态压缩DP)

把每一包糖果用二进制表示 v [ j ]

然后从 0 开始遍历每一个 状态 i ,
则 i | v [ j ] 是可以分配到的状态 ,这个状态需要的糖果包数量为 min ( dp [ i | v [ j ]
, dp [ i ] + 1 )

#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=110,M=20,K=20;
LL n,m,k,ans,dp[1<<20],v[1<<20];

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n>>m>>k;
	fill(dp,dp+(1<<20),LLONG_MAX-10);
	for(int i=1;i<=n;i++)
	{
		int h=0,p=0;
		for(int j=1;j<=k;j++)
		{
			cin>>p;
			h|=1<<(p-1);
		}
		dp[h]=1;
		v[i]=h;
	}
	
	for(int i=0;i<(1<<m);i++)
	{
		for(int j=1;j<=n;j++)
		{
			dp[i|v[j]]=min(dp[i|v[j]],dp[i]+1);
		}
	}
	
	if(dp[(1<<m)-1]==LLONG_MAX-10)
	{
		cout<<-1;
	}
	else
	{
		cout<<dp[(1<<m)-1];
	}
	return 0;
}




蚂蚁感冒

纯思维题
md写了两千多长度的屎山发现写不下去一看题解四百多长度

找到 初始感冒蚂蚁 左边向右的数量 L,右边向左的数量 R

如果 初始感冒蚂蚁向左
    如果 L == 0
        则 ans == 1
    如果 L != 0
        ans = L + R + 1

可以想象一下牛顿摆那种感觉,碰撞后反弹可视作两个物体穿过了彼此(速度始终不变且都等于同一个常数 1 )

点击查看代码
#include <bits/stdc++.h>
typedef long long int LL;
using namespace std;
const int N=1e5+10;
LL n,m,a[N],ans,l,r;

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	
	for(int i=2;i<=n;i++)
	{
		if(abs(a[i])<abs(a[1])&&a[i]>0) l++;
		else if(abs(a[i])>abs(a[1])&&a[i]<0) r++;
	}
	
	if(a[1]<0)
	{
		if(l==0) ans=1;
		else ans=l+r+1; 
	}
	else if(a[1]>0)
	{
		if(r==0) ans=1;
		else ans=l+r+1; 
	}
	cout<<ans;
	return 0;
}

posted @ 2025-03-25 20:30  石磨豆浆  阅读(28)  评论(0)    收藏  举报