主页
最近更新
雨花区“青苗杯”2023小学组 赛题分析
最后更新于 2025-05-01 23:13:02
作者
foryou_
分类
个人记录
复制 Markdown
更新文章内容
## T1: 简单数学题。 设头数为 $a$,脚数为 $b$,有: $$ \because \ \begin{cases} 2x+4y=a \\ 4x+6y=b \\ \end{cases} $$ $$ \therefore \ \begin{cases} 2x+2y=b-a \\ x+y=\dfrac{b-a}{2} \\ \end{cases} $$ 知道了 $x+y$,就可以按照传统“鸡兔同笼”的方法做这道题了。(~~其实还没有解方程快~~) 注意判断无解时不仅要判断头、脚数,还要纳入 $x<0$ 与 $y<0$ 的情况。 ### *code* ```cpp #include<bits/stdc++.h> using namespace std; long long a,b; long long sum; long long x,y; int main(){ scanf("%lld%lld",&a,&b); sum=abs(b-a)/2; y=(b-sum*4)/2; x=sum-y; if(x*2+y*4!=a||x*4+y*6!=b||x<0||y<0){ cout<<"Impossible!"; return 0; } printf("%lld %lld\n",x,y); return 0; } ``` ## T2: 比较恶心的一道码农题,调了好久才过。。。 大致思路是这样的: - 先确定两个声母。尝试第一个字母作为声母,若不合法,在尝试用前两个作为声母;若还不合法,则说明整个单词都是韵母,将声母设置为空串。 - 再确定两个韵母。截取声母后的字符串为韵母,若不合法,则将声母转化为另一种(单转双、双转单);若还不合法,则说明整个单词都是韵母,将声母设置为空串。 - 判断声母、韵母的异同,并输出判断结果。 ### *code* ```cpp #include<bits/stdc++.h> using namespace std; string s1,s2; string sh1,sh2,yu1,yu2; int main(){ cin>>s1>>s2; sh1=s1[0],sh2=s2[0]; if(sh1!="b"&&sh1!="p"&&sh1!="m"&&sh1!="f"&&sh1!="d"&&sh1!="t"&&sh1!="n"&&sh1!="l"&&sh1!="g"&&sh1!="k"&&sh1!="h"&&sh1!="j"&&sh1!="q"&&sh1!="x"&&sh1!="r"&&sh1!="z"&&sh1!="c"&&sh1!="s"&&sh1!="y"&&sh1!="w"){ sh1="",sh1+=s1[0],sh1+=s1[1]; if(sh1!="zh"&&sh1!="sh"&&sh1!="ch") sh1=""; } if(sh2!="b"&&sh2!="p"&&sh2!="m"&&sh2!="f"&&sh2!="d"&&sh2!="t"&&sh2!="n"&&sh2!="l"&&sh2!="g"&&sh2!="k"&&sh2!="h"&&sh2!="j"&&sh2!="q"&&sh2!="x"&&sh2!="r"&&sh2!="z"&&sh2!="c"&&sh2!="s"&&sh2!="y"&&sh2!="w"){ sh2="",sh2+=s2[0],sh2+=s2[1]; if(sh2!="zh"&&sh2!="sh"&&sh2!="ch") sh2=""; } int len1=sh1.length(),len2=sh2.length(); yu1=s1.substr(len1),yu2=s2.substr(len2); if(yu1[0]!='a'&&yu1[0]!='o'&&yu1[0]!='e'&&yu1[0]!='i'&&yu1[0]!='u'&&yu1[0]!='v'){ sh1="",sh1+=s1[0],sh1+=s1[1]; if(sh1!="zh"&&sh1!="sh"&&sh1!="ch") sh1=""; } if(yu2[0]!='a'&&yu2[0]!='o'&&yu2[0]!='e'&&yu2[0]!='i'&&yu2[0]!='u'&&yu2[0]!='v'){ sh2="",sh2+=s2[0],sh2+=s2[1]; if(sh2!="zh"&&sh2!="sh"&&sh2!="ch") sh2=""; } len1=sh1.length(),len2=sh2.length(); yu1=s1.substr(len1),yu2=s2.substr(len2); if(sh1!=sh2&&yu1!=yu2) cout<<0; if(yu1==yu2&&sh1!=sh2) cout<<1; if(sh1==sh2&&yu1!=yu2) cout<<2; if(sh1==sh2&&yu1==yu2) cout<<3; return 0; } ``` ## T3: 思路比较难想的分类讨论题,尤其是那个 ```exc``` 函数。。。 记总时间为 $t$。分三种情况考虑: - 背向而行 - 情况 $1$:靠左的人先到点 $0$。 - $t \gets t + \dfrac{x_1}{v_1}$。 - 靠左的人 $x_1 \gets 0 \ , \ d_1 \gets \ !d_1 $。 - 靠右的人 $x_2 \gets x_2 + \dfrac{x_1}{v_1} \times v_2$。 - 情况 $2$:靠右的人先到点 $l$。 - $t \gets t + \dfrac{l-x_2}{v_2}$。 - 靠右的人 $x_2 \gets l \ , \ d_2 \gets \ !d_2 $。 - 靠左的人 $x_1 \gets x_1 - \dfrac{l-x_2}{v_2} \times v_1$。 考虑完上面几种情况后,用 ```exc``` 函数将第一人的方向改为朝左具体实现如下: ```cpp void exc(){ if(d1){ x1=l-x1,x2=l-x2; d1=!d1,d2=!d2; } } ``` - 追及相遇 - 情况 $1$:靠右人能追上靠左人。 直接返回 $t + \dfrac{\lvert x_1-x_2 \rvert}{\lvert v_1-v_2 \rvert}$ 即可。 - 情况 $2$:靠右人追不上。 将靠右人坐标镜像(即设置为在数轴上的对称点)即可转化为相向而行的问题求解。 - 相向而行 直接返回 $t + \dfrac{\lvert x_2-x_1 \rvert}{v_1+v_2}$ 即可。 判断无解:仅需判断 $v_1$ 或 $v_2$ 是否为 $0$ 即可。 注意分类讨论前需进行一次 ```exc``` 方可开始。 ### *code* ```cpp #include<bits/stdc++.h> using namespace std; struct node{ double x; int v,d; }; double l; node a,b; void exc(){ if(a.d){ a.x=l-a.x,b.x=l-b.x; a.d^=1,b.d^=1; } } double work(){ double t=0; exc(); if(a.d!=b.d&&a.x<b.x){ if(a.x*b.v<(l-b.x)*a.v){ t+=a.x/a.v; b.x+=t*b.v; a.x=0,a.d=1; } else{ t+=(l-b.x)/b.v; a.x-=t*a.v; b.x=l,b.d=0; } exc(); } if(a.d==b.d){ if((a.x*b.v<=b.x*a.v)^(a.x<b.x)) return t+abs(b.x-a.x)/abs(b.v-a.v); else a.x=-a.x; } return t+abs(a.x-b.x)/(a.v+b.v); } int main(){ cin>>l; cin>>a.x>>a.v>>a.d; cin>>b.x>>b.v>>b.d; if(a.v==0&&b.v==0){ printf("Impossible!"); return 0; } else{ cout<<setprecision(5)<<fixed<<work(); return 0; } return 0; } ``` ## T4: 小清新数据结构题。 考虑离线求出每个事件后的最大值与最小值,并存放于数组中。 - 最大值: 直接遍历所有事件求最大值即可。 - 最小值: 将初值设为第 $m$ 个事件后的最小值,并倒序处理所有事件求最小值即可。 ### *code* ```cpp #include<bits/stdc++.h> using namespace std; int n,m; struct node{ int p,v; long long mx,mn; }e[500031]; long long a[50031]; int main(){ scanf("%d%d",&n,&m); //max element for(int i=1;i<=m;i++){ cin>>e[i].p>>e[i].v; e[i].mx=max(e[i-1].mx,a[e[i].p]+=e[i].v); } //min element e[m].mn=e[m].mx; for(int i=1;i<=n;i++) e[m].mn=min(e[m].mn,a[i]); for(int i=m;i>1;i--) e[i-1].mn=min(e[i].mn,a[e[i].p]-=e[i].v); for(int i=1;i<=m;i++) printf("%lld ",e[i].mx-e[i].mn); return 0; } ```
Loading...
点赞
1
收藏
0