欢乐赛#45 官方题解
2025-04-16 07:47:40
发布于:浙江
欢乐赛#45 官方题解
T1算式输出
第一题没有输入,主要考察输出代码的使用,需要区分算式中的文字部分和计算部分。
文字部分原封不动地输出,需要放在双引号内。计算部分则需要进行计算,直接写上算式即可得到计算结果。
#include <iostream>
using namespace std;
int main(){
cout<<"2025*410="<<2025*410;
return 0;
}
T2球体体积
第二题计算球体的体积,题目给出了计算公式,直接套用公式计算即可。
这里注意数据类型,数据要保留小数部分,需要用double类型存储结果。
算式中的 要写成 ,否则两个整数计算的结果还是整数,会丢失小数部分,导致后续结果错误。也可以把这部分的计算放到半径之后,确保计算过程中结果始终是浮点数。
#include <iostream>
using namespace std;
int main(){
double r;
cin>>r;
double pi=3.1415926;
double v=4.0/3*pi*r*r*r;
printf("%.4lf",v);
return 0;
}
T3最后期限
第三题要求计算时间,从8点15分开始往回推,减去每件事消耗的时间,要注意单位换算。
题目中提示了分钟被减到负数的情况,当分钟不够时可以把1小时换算成60分钟继续计算。
可以在减去每个时间后判断分钟是否是负数,也可以直接减去所有的时间再一次性将欠的分钟补上。
参考代码中是采用了统一换成小单位计算的方法,等计算结束后再换算成最终输出。这个方法可以避免出现负数和多次检查进位借位的情况。
#include <iostream>
using namespace std;
int main(){
int a,b,c;
cin>>a>>b>>c;
int ans=8*60+15;
ans=ans-a-b-c-5;
int x,y;
x=ans/60;
y=ans%60;
cout<<x<<" "<<y<<endl;
return 0;
}
T4分数查询
第四题根据名字查询分数,需要判断字符串匹配并找到对应分数。
每个人的信息可以通过结构体存储,或者用多个数组存储,通过下标存储顺序,下标相同的数组元素为同一个人的信息。
参考代码中字符串匹配使用了string所以可以直接比较。如果存储使用的是char数组,则需要使用strcmp函数进行字符串匹配。
#include <bits/stdc++.h>
using namespace std;
string s[110];
int x[110],y[110],z[110];
int main(){
int n,q;
cin>>n;
for(int i=1;i<=n;i++){
cin>>s[i]>>x[i]>>y[i]>>z[i];
}
cin>>q;
while(q--){
string t;
cin>>t;
for(int i=1;i<=n;i++){
if(t==s[i]){
cout<<x[i]<<" "<<y[i]<<" "<<z[i]<<endl;
}
}
}
return 0;
}
T5奖品分发
第五题排顺序,需要使用结构体排序的方法。申请结构体变量存储信息,并定义cmp函数来确定排序规则,最后用sort函数进行排序。
参考代码中定义了结构体类型Student,存储了学生的学号、总分、进步情况。
cmp函数中先比较进步情况,如果进步情况相同,则总分大的排在前面。
如果总分也一样,则比较学号,学号小的排在前面。
#include <bits/stdc++.h>
using namespace std;
struct Student {
int a,x,y;
};
int n;
Student s[550];
bool cmp(Student x,Student y){
if(x.y==y.y){//进步情况
if(x.x==y.x){//总分
return x.a<y.a;//学号
}
else return x.x>y.x;
}
else{
return x.y>y.y;
}
}
int main() {
cin>>n;
for(int i=1;i<=n;i++){
cin>>s[i].a>>s[i].x>>s[i].y;
}
sort(s+1,s+n+1,cmp);
for(int i=1;i<=n;i++){
cout<<s[i].a<<endl;
}
return 0;
}
T6方阵排列
第六题是比较麻烦的二维数组遍历,需要思考清楚当前所处的情况和下一步的操作,此类题目建议多画图寻找规律,并写出关键节点的情况,如本题中每一圈遍历时的转弯点坐标情况。
本题要求的回型遍历其实类似于螺旋遍历,只是每圈顺时针和逆时针方向不同,需要区分代码中循环的初始值和条件。
#include <bits/stdc++.h>
using namespace std;
int n;
int a[110][110];
int num;//表示当前位置编号 从1~n*n
int flag;//表示当前圈顺序 1顺时针 0逆时针
int main() {
cin>>n;
num=1;
flag=1;//从1号开始 第一圈顺时针
for(int k=1;k<=n/2;k++){//第k圈
if(flag){//顺时针
for(int j=k;j<=n-k+1;j++){//第k行 第k~n-k+1列
a[k][j]=num;
num++;
if(num==n*n){
break;
}
}
for(int i=k+1;i<=n-k+1;i++){//倒数第k列即n-k+1列 第k+1~n-k+1行
a[i][n-k+1]=num;
num++;
if(num==n*n){
break;
}
}
for(int j=n-k;j>=k;j--){//倒数第k行即n-k+1行 第n-k~k列
a[n-k+1][j]=num;
num++;
if(num==n*n){
break;
}
}
for(int i=n-k;i>=k+1;i--){//第k列 第n-k行~k+1行
a[i][k]=num;
num++;
if(num==n*n){
break;
}
}
flag=0;
}
else{//逆时针
for(int i=k;i<=n-k+1;i++){//第k列 第k行~n-k+1行
a[i][k]=num;
num++;
if(num==n*n){
break;
}
}
for(int j=k+1;j<=n-k+1;j++){//倒数第k行即n-k+1行 第k+1~n-k+1列
a[n-k+1][j]=num;
num++;
if(num==n*n){
break;
}
}
for(int i=n-k;i>=k;i--){//倒数第k列即n-k+1列 第n-k~k行
a[i][n-k+1]=num;
num++;
if(num==n*n){
break;
}
}
for(int j=n-k;j>=k+1;j--){//第k行 第n-k~k+1列
a[k][j]=num;
num++;
if(num==n*n){
break;
}
}
flag=1;
}
if(num==n*n){
break;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(j!=1){
cout<<" ";
}
cout<<a[i][j];
}
cout<<endl;
}
return 0;
}
对于螺旋遍历的代码,还有一种方法是用变量记录剩余要输出的位置下标,可以更容易地控制上下左右的边界位置。
int u=1,d=n,l=1,r=n;//表示剩余要输出的最上方一行(最小行号)为i
while(num<n*n){
if(flag){//顺时针
for(int j=l;j<=r;j++){//第u行 第l~r列
a[u][j]=num;
num++;
if(num==n*n){
break;
}
}
u++;//这一行输出完 剩余要输出的最上方行号要+1
for(int i=u;i<=d;i++){//第r列 第u~d行
a[i][r]=num;
num++;
if(num==n*n){
break;
}
}
r--;//这一列输出完 剩余要输出的最右方列号要-1
//for循环输出最下方行 d--
//for循环输出最左方列 l++
}
else{//逆时针
for(int i=u;i<=d;i++){//第l列 第u~d行
a[i][l]=num;
num++;
if(num==n*n){
break;
}
}
l++;//这一列输出完 剩余要输出的最左方列号要+1
//for循环输出最下方行 d--
//for循环输出最右方列 r--
//for循环输出最上方行 u++
}
}
这里空空如也
有帮助,赞一个