- xxx
2025花都区少年宫信息赛编程题部分
- 2025-5-30 20:54:00 @
各位参赛选手家长、指导老师:
大家好!经过严格评审,软件编程赛项线下决赛名单已确定,现将相关事宜通知如下:
一、决赛名单公布 本次公布的名单为软件编程赛项线下决赛入围名单,成功入选的选手请认真备赛。
二、奖项说明 所有比赛成绩(奖项)将于下周内统一发布。未入选决赛的选手,不代表未获奖,最终结果请耐心等待统一公布 。
三、决赛联系事宜 线下决赛将于6月1日在花都区青少年文化宫(市民广场宫)进行,请参加决赛选手的联系人或指导老师,尽快联系赛事黄烽晋老师沟通后续安排。
一、线下决赛时间: 6月1日暂定上午9:00-11:30,具体时间和课室安排等群上安排通知 二、决赛前准备内容: 各组别选手在编程题中三选一自行完成,并将该题目代码文件命名“姓名+赛项+组别”发送至邮箱1601523494@qq.com,请在5月31日中午12点前完成发送。 三、线下决赛内容: 根据选手发送的题目代码,评委将询问选手关于题目的解题思路等。
比赛题目点击这里查看和测试
题解查看下面评论区
3 条评论
-
gf23132 LV 7 @ 2025-5-31 0:39:37
第三题:木材切割(二分查找)
#include<bits/stdc++.h> using namespace std; int main(){ int n,k; cin>>n>>k; int L[n]; for(int i=0;i<n;i++){ cin>>L[i]; }//输入 int left=1,right=0;//left最小可能长度 for(int i=1;i<n;i++){ if(L[i]>right){ right=L[i]; } }//搜索right的最大值,也可以用*max_element(L,L+n) int ans=0;//存储答案 while(left<=right) { int mid=left+(right-left)/2;//找中间值,防止溢出,从left开始,加上区间长度的一半 //left+(right-left)=left+right/2-left/2=(left+right)/2 long long sum=0;//存储mid时能切出的总段数 for(int i=0;i<n;i++) { sum+=L[i]/mid;//sum+=每根原木能切出的段数 } if(sum>=k) { ans=mid; left=mid+1;//如果能切更大的段数,向右搜索,尝试更大的数 }else{ right=mid-1;//否则尝试更小的数,向左搜索 } } cout<<ans<<endl; return 0; } ``` `
-
2025-5-30 21:56:41@
第二题:评选
#include <iostream> #include <algorithm> using namespace std; struct stu { string s;//干员名称 int d, f, g, ni; //d:任务危险程度 //f:任务评分 //g:任务奖金 //ni:编号(资历) }a[200005];//储存n个人 int n, glen, alen;//glen:“神”的数量 alen:非神的数量 string g[100005]; bool cmp(stu x, stu y) { //如果危险程度不同,就按危险程度从大到小排序 if (x.d != y.d)return x.d > y.d; //如果任务评分不同,就按评分从大到小排序 if (x.f != y.f)return x.f > y.f; //如果奖金不同,就按奖金从大到小排序 if (x.g != y.g)return x.g > y.g; //否则就按资历从小到大排序 return x.ni < y.ni; } int main() { cin >> n;//有n个人 for (int i = 1; i <= n; i++) { //第i个人的数据 string ns; int nd, nf, ng; cin >> ns >> nd >> nf >> ng; //封为“神”,存入g if (nd > 200) { g[++glen] = ns; continue; } //否则就是普通人 a[++alen] = {ns, nd, nf, ng, i}; } //先输出“神” for (int i = 1; i <= glen; i++) { cout << g[i] << "\n"; } //排序 sort(a + 1, a + alen + 1, cmp); //输出 for (int i = 1; i <= alen; i++) { cout << a[i].s << "\n"; } return 0; }
-
2025-5-30 21:01:49@
第一题:体检
这题就是普通的模拟题,也可以输入时候先用二维数组存储然后再统一处理求平均数,也可以在线形式边输入就直接处理输出结果无需存储数据。
唯一要注意的是,输出结果有的是整数,有的要保留两位小数的实数
#include <iostream> #include <iomanip> using namespace std; int n,m; int main(){ cin>>n>>m; for(int i=1;i<=n;i++){//有n个人 int x,s=0; for(int j=1;j<=m;j++){//每个人进行m次体检 cin>>x;//输入健康值 s+=x;//健康值求和 } if(s%m==0) //如果能整除则输出整数 cout<<s/m<<" "; else//否则输出保留两位小数 cout<<fixed<<setprecision(2)<<1.0*s/m<<" ";//1.0*s的作用是将结果转为实数 } return 0; }
第二题:评选
这是一道结构体存储数据,然后根据排序规则排序的题目
#include <bits/stdc++.h> using namespace std; struct stu{//定义员工结构体 string s; int d,f,g,id; }a[200005]; string s; int n,n2,d,f,g; bool cmp(stu x,stu y){//sort比较规则函数 return tie(x.d,x.f,x.g,y.id)>tie(y.d,y.f,y.g,x.id); } int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>s>>d>>f>>g; if(d>200){//如果危险程度超过200,神干员直接输出 cout<<s<<endl; }else{//否则存储员工信息到a[] n2++;//非神干员数 a[n2].s=s;a[n2].d=d;a[n2].f=f;a[n2].g=g;a[n2].id=i; } } sort(a+1,a+n2+1,cmp);//按规则排序 for(int i=1;i<=n2;i++){ cout<<a[i].s<<endl;//输出剩余n2名干员的名称 } return 0; }
cmp部分不熟悉tie或者tuple的,可用用以下代码替换:
bool cmp(stu x,stu y){ if(x.d!=y.d)return x.d>y.d; if(x.f!=y.f)return x.f>y.f; if(x.g!=y.g)return x.g>y.g; return x.id<y.id; }
第三题:切割木材
这是一题求最小值最大的二分答案题
先假设题目的答案在[L,R)区间范围内,然后通过验证中间值m=(L+R)/2,是否可行,逐步对半缩小答案范围,直到最终[L,R)之间只有一个符合要求的数即为答案
二分查找的写法按照区间设置的不同有三种写法,详情请点击查看关于二分法的三种写法分析
#include <bits/stdc++.h> using namespace std; int n,k,a[1000005],l,r,m; bool check(int x){//判断按照x长度切割是否可行 int cnt=0; for(int i=1;i<=n;i++){ cnt+=a[i]/x; if(cnt>=k)return true;//如果能达到k段,则可行 } return false; } int main(){ //二分答案,求最小值最大,采用左闭右开区间二分查找答案值 cin>>n>>k; for(int i=1;i<=n;i++){ cin>>a[i]; r=max(r,a[i]);//答案的最大值无法超过a[i]的最大那根 } l=0;r++;//假设答案值在[1,r)之间所以r要比答案多1 while(r-l>1){//采用左闭右开区间方式的二分答案查找 int m=(r-l)/2+l;//等价于=(r+l)/2,这样写防止r+l爆int范围 if(check(m)){//如果m符合切割要求 l=m;//m可能是答案,缩小l }else{//否则m不符合切割要求 r=m;//说明m不是答案,缩小r } } cout<<l;//如果l为0,则说明无自然数解 return 0; }
- 1