大类07洛谷赛的题解
首先要感谢所有参赛提交的同学!大家的每一次提交对我们而言都意义非凡!谢谢大家的参与!
接下来由我们出题组对题目进行讲解
总览
- 简单判断(杨)
- 数组(伍)
- 字符串(杨)
- 循环判断(杨)
- 双指针(伍)
每题的题解和参考代码
1
坐电梯上一层楼的时间为5s,走楼梯上一层楼用时11s,但是电梯最多只能上到7楼,所以小薛住的地方的层数小于等于7的话就可以直接通过电梯到达,如果大于7的话就要先坐电梯到达7楼在走电梯到达小薛住的位置。
第一种情况:n(小薛住的楼层)<=7
从第一楼到第二楼(假设小薛住在2楼)用时3s
从第一楼到第n楼用时:3+5(n-2)
第二种情况:n>7
先从第一楼到第7楼用时:3+5(7-2)
从第7楼到第8楼(假设小薛住在8楼)用时:7s
从第7楼到第n楼用时:7+11(n-8);
所以从第一楼到第n楼用时:3+5(7-2)+7+11*(n-8)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int N,m;
//楼层数
cin >> N;
//直接坐电梯
if ( N <= 7 )
{
m = 3 + 5 * ( N - 2 );
}
//在坐电梯的基础上走楼梯
else
{
m = 3 + 5 * ( 7 - 2 ) + 7 + 11 * ( N - 8 );
}
cout << m;
return 0;
}
2
第二题是个数组题。题目要求寻找最小值和它的下标。只需要一个变量来存储最小值的下标即可。参考题目是
https://www.acwing.com/problem/content/744/
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int main()
{
int t;
cin >> t;
//t组数据
while ( t -- )
{
//minn存放最小值的下标
int n,minn = 0;
cin >> n;
int a[N];
//输入原始数据
for ( int i = 0; i < n; i ++ )
{
cin >> a[i];
}
//找到最小值的下标
for ( int j = 0; j < n; j ++ )
{
//只有当有值比当前的最小值还小时才会更新下标
if ( a[j] < a[minn])
{
minn = j;
}
}
cout << a[minn] << endl;
cout << minn << endl;
}
return 0;
}
3
数字三角形和数字矩形都是从n开始的,然后以1递加,可以定义一个整数s=n,三角形和矩形都是n行和n列,可以进行两个嵌套的for循环外层的循环里面套嵌两个for循环来输出,里面的第一个来输出空格,第二个for循环来输出数字,如果数字s小于10则输出0s,如果s>=100,在对s%100进行一次判断看s%100是否大于10,如果小于10则输出0(s%100),否则输出s%100,如果s>10&&s<100则输出s,第2个循环后输出换行。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int n, row;
cin >> n;
row = n;
for(int i = 1; i <= row; ++i) //行
{
//先输出前面的空格
for(int j = (row - i) * 2; j > 0; --j) cout << ' ';
//输出数字部分
for(int j = i; j > 0; --j)
{
//小于10的有前导0
if(n < 10) cout << 0;
int x = n;
x %= 100;
//大于99的要取模
if(x < 10 && n > 10) cout << 0;
cout << x;
n++;
}
//每行结束要输出换行
puts("");
}
puts("");
n = row;
//下面的这个是正方形,注意前导0 和 大于99的情况
for(int i = 0; i < row; ++i)
{
for(int j = 0; j < row; ++j)
{
if(n < 10) cout << 0;
int x = n;
x %= 100;
if(x < 10 && n > 10) cout << 0;
cout << x;
n++;
}
puts("");
}
return 0;
}
4
定义两整数count1和count2分别来存放字符数组中小写字母的个数和大写字母的个数,在定义一个字符数组类进行输出,先判断小写字母个数和大写字母个数的关系,再遍历一遍原字符数组将字母按要求转换。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int num1 = 0, num2 = 0;
int n;
string s = "", ans = "";
//输入时要把数字的换行也输入进来,不然无法输入字符串。
//cin 遇到空格或换行结束,输入可能含有空格,所以不能用cin,而要用getline
//因为getline遇到换行终止。所以一定要将数字后面的换行符吸收掉
scanf("%d\n", &n);
//字符串可能含有空格,所以要用`getline`输入一整行
getline(cin, s);
//算出大写和小写的字母分别有多少个
for(auto it : s)
if(it >= 'a' && it <= 'z') num1 ++;
else if(it >= 'A' && it <= 'Z') num2 ++;
int flag = num1 >= num2 ? 1 : 0;
for(auto it : s)
//只要求转换字母
if((it >= 'a' && it <= 'z') || (it >= 'A' && it <= 'Z'))
//按照题目要求由大写转小写 或 由小写转大写
if(flag)
{
if(it >= 'A' && it <= 'Z')
ans += it + 'a' - 'A';
else
ans += it;
}
else
{
if(it >= 'A' && it <= 'Z') ans += it;
else ans += it + 'A' - 'a';
}
cout << ans;
return 0;
}
如果不了解string
用法的同学也可以看下下面的C语言写法
#include<stdio.h>
#include<string.h>
const int N = 120;
int main()
{
int n, count1 = 0, count2 = 0;
//输入时要把数字的换行也输入进来,不然无法输入字符串
scanf("%d\n",&n);
char s[N], a[N];
//定长输入
for ( int i = 0; i < n; i ++ )
{
scanf("%c", &s[i]);
if ( s[i] >= 'a' && s[i] <= 'z')
{
count1 ++;
}
if ( s[i] >= 'A' && s[i] <= 'Z')
{
count2 ++;
}
}
//'\0'表示结尾
s[n]='\0';
int k = 0;
for ( int j = 0; j < n; j ++)
{
if ( count2 > count1 )
{
if ( s[j] >= 'a' && s[j] <= 'z')
{
a[k] = s[j] - 'a' + 'A';
k ++;
}
else if ( s[j] >= 'A' && s[j] <= 'Z')
{
a[k] = s[j];
k ++;
}
}
else
{
if ( s[j] >= 'a' && s[j] <= 'z' )
{
a[k] = s[j];
k ++;
}
else if ( s[j] >= 'A' && s[j] <= 'Z' )
{
a[k] = s[j] - 'A' + 'a';
k ++;
}
}
}
//结尾加上'\0'
a[k] = '\0';
puts(a);
return 0;
}
5
这题是个双指针类型题目。用到的知识点是固定长度的滑动窗口。根据下面这题改编的
https://leetcode-cn.com/problems/grumpy-bookstore-owner/
这题我们先确定老师一定不会发现小明偷吃时小明能吃的总量,再用一个定长的窗口从左往右滑动,找到窗口能够包含的最大的额外摄入量即可
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int T, n, ttime;
const int N = 1e5;
int a[N];
bool b[N];
int maxnum(int a[], bool b[], int ttime, int n)
{
int ans = 0;
//先加上一定不会被发现的量
for(int i = 0; i < n; ++i) if(!b[i]) ans += a[i], a[i] = 0;
int tmp = 0;
//初始化滑动窗口的初始值
for(int i = 0; i < ttime; ++i) tmp += a[i];
//i j双指针
int maxn = tmp, i = 0, j = ttime - 1;
//固定长度向右移
while(j < n - 1)
{
//加上右边(新)的同时减去左边(旧)的
tmp = tmp + a[j + 1] - a[i];
//比较计算出窗口能够容纳的最大摄入量
maxn = max(maxn, tmp);
//滑动窗口往右滑动
++i, ++j;
}
//一定不会被发现的量 + 额外的量
return maxn + ans;
}
int main()
{
cin >> T;
while(T--)
{
//ttime是滑动窗口的长度
cin >> ttime >> n;
for(int i = 0; i < n; ++i) cin >> a[i];
for(int i = 0; i < n; ++i) cin >> b[i];
cout << maxnum(a, b, ttime, n) << endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现