转生成为 C 语言糕手——语法篇
A(广告位)关注编程爱好者协会喵~ —— 编程爱好者协会招新群:932267597(QQ)
题目描述
简单介绍一下我们的编程爱好者协会喵~
宗旨喵~:
培养学生对算法及程序设计的兴趣与技能,组织学生参加各种知名国家、省市级程序设计比赛,以及大型网站的前后端与数据库的开发,提升学生的学习能力与团队合作精神,增强学生的个体竞争力。提升我校在全国高校的知名度;
部门划分喵~:
1. 策划部
●各种比赛的策划与组织;
2. 宣传部
●负责对各种活动的宣传;
3. 媒体部
●运营各种自媒体;
4. 技术部
●有很高的编程水平,负责在讲座时传授知识;
●负责某些比赛的出题,准备题解和赛后讲题;
主要活动喵~:
●一些编程知识讲座,程序设计语言基础或者是算法;
●各种编程比赛,如天梯赛,蓝桥杯,全国大学生程序设计比赛和国际大学生程序设计比赛;
●各种项目实战;
如果你已经完全了解以上内容了,请输出 “收到喵”
加群喵~ 加群谢谢喵~
输入
无
输出
我也不知道输出什么喵~
可能在题目里面吧
样例输入 Copy
无
样例输出 Copy
我也不知道是什么喵~(不要直接输出这一句喵~)
提示
最近我们编程爱好者协会要招新了呢!!!
这是今年我校新成立的协会喵~
菜姬作为协会的老东西被拉来宣传了喵~
关注编程爱好者协会喵~ 谢谢喵~
编程爱好者协会招新群:932267597(QQ)
进群喵~ 求求了喵~
原代码
//水题
#include <iostream>
using namespace std;
int main()
{
cout << "收到喵" << endl;
return 0;
}
B 正经的签到
题目描述
Zero 是一位善良的人,他不希望大家正确通过题目数为 0,所以他想到一个简单题,来帮助大家完成签到。
Zero 在网上发现了一串神秘数字 “998244353”,他对这串数组很感兴趣,现在他想知道这个数字的每一位的和与每一位的乘积,但不幸的是,Zero 并不擅长数学计算。
现在请你来告诉 Zero 这两个数字。
输入
无
输出
输出 998244353 各数位的和 x 与积 y,每个数字占一行
样例输入 Copy
无
样例输出 Copy
x
y
提示
请不要直接输出字母 x, y !!!
源代码
//水题
#include <iostream>
using namespace std;
int main()
{
int a[10] = {0,9,9,8,2,4,4,3,5,3};
int ans1 = 0,ans2 = 1;
for(int i = 1;i <= 9;i ++ )ans1 += a[i];
for(int i = 1;i <= 9;i ++ )ans2 *= a[i];
cout << ans1 << endl << ans2 << endl;
return 0;
}
C 粗心的菜姬酱
题目描述
众所周知,菜姬酱是一个粗心的孩子。可怜的菜姬酱每次回答 Zero 老师的问题时都会由于各种马虎导致回答错误。善良的你不忍心看到菜姬酱由于回答错误而哭哭啼啼,你决定帮助她回答 Zero 老师的问题。
输入三个整数 a, b, c ,请判断 a+b 是否等于 c ; a 和 b 的最大值是否等于 c ; a 的 b 次方是否等于 c
对于每个问题正确输出 YE5,错误输出 N0,之后输出换行。
输入
输入三个整数 a, b, c (1 ≤ a, b, c ≤ 5 )
输出
输出三行,每行是对应问题的答案
样例输入 Copy
1 1 1
样例输出 Copy
N0
YE5
YE5
提示
你也会像菜姬酱一样粗心吗???
源代码
//练心眼子题,是0不是o,是5不是s
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int a,b,c;
cin >> a >> b >> c;
if(a + b == c)cout << "YE5" << endl;
else cout << "N0" << endl;
if(max(a,b) == c)cout << "YE5" << endl;
else cout << "N0" << endl;
if(pow(a,b) == c)cout << "YE5" << endl;
else cout << "N0" << endl;
return 0;
}
D 平均分!
题目描述
做了前面的题,我们都知道 Zero 哥哥不擅长数学计算,但是他又想知道他的平均成绩,快动用你们聪明的小脑袋帮他算一算吧
输入
先输入一行一个整数 n ( 1 ≤ n ≤ 1000 )
接下来输入一行 n 个整数 a1, a2, a3, ..., an 分别代表 Zero 哥哥的分数
再接下来再输入一行 n 个实数 b1, b2, b3, ..., bn 分别代表该分数对应的学分
输出
一行一个实数
,结果保留两位小数(四舍五入)
样例输入 Copy
6
92 98 95 93 91 100
1 1 4 5 1 4
样例输出 Copy
95.38
提示
是求和符号,保证
源代码
//水题
#include <iostream>
using namespace std;
const int N = 1010;
int a[N];
double b[N];
int main()
{
int n;
cin >> n;
for(int i = 1;i <= n;i ++ )cin >> a[i];
for(int i = 1;i <= n;i ++ )cin >> b[i];
double avg = 0,num = 0,deno = 0;
for(int i = 1;i <= n;i ++ )
{
num += a[i] * b[i];
deno += b[i];
}
avg = num * 1.0 / deno;
printf("%.2lf",avg);
return 0;
}
E 无奈的打印
题目描述
Zero 是一名学习委员,他时常需要去打印店打印文件,一天他去打印店打印文件,他需要打印的文件是单面的,但意外发生了,打印机只能进行双面打印,Zero 无奈的选择了双面打印。现在问题来了,他只知道单面打印的文件一共有 x 张,却不知道双面打印需要多少张打印纸。你能告诉 Zero 他需要多少张打印纸吗?
输入
多组测试样例
第一行 一个测试样例数目 T (T <= 2000)
接下来 T 行,每行一个整数 x (x > 0)
保证 x < INT_MAX
输出
每个测试样例输出占一行
样例输入 Copy
2
4
7
样例输出 Copy
2
4
源代码
//水题
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int t;
cin >> t;
while(t -- )
{
int x;
cin >> x;
cout << (x + 1) / 2 << endl;
}
return 0;
}
F 谁才是班委
题目描述
Zero 上大一的时候竞选过班委,通过询问辅导员他明白了如何竞选班委:学生投票数最多的那个人就可以成为班委。现在有 n 个人在竞选班委,他们的编号从 1 到 n,一共有 m 个人投票。但有的同学在捣乱,他们投的编号并不在 1 ~ n 中,现在你需要正确统计统计票数,并且告诉 Zero,谁才是班委,输出那个人的编号。(数据保证至少有一位同学的投票是正常的)
输入
第一行输入 n 和 m,空格隔开
接下来 m 行,每行一个 x,代表有同学投给 x 一票
(1 <= n <= 2000,1 <= m <= n,x 是 int 类型的整数)
输出
输出一个整数,代表获得投票数最多的班委。(如果有平票,则输出编号最小的同学)
样例输入 Copy
7 6
1
1
-3
5
5
10
样例输出 Copy
1
提示
注意数据范围
源代码
//水题
#include <iostream>
using namespace std;
const int N = 2000 + 20;
int a[N];
int main()
{
int n,m;
cin >> n >> m;
while(m -- )
{
int id;
cin >> id;
if(id >= 1 && id <= n)a[id] ++ ;
}
int maxnum = -1,ansid = -1;
for(int i = 1;i <= n;i ++ )
{
if(maxnum < a[i])
{
maxnum = a[i];
ansid = i;
}
}
cout << ansid << endl;
return 0;
}
G 买时装!
题目描述
是该沙漠同学很喜欢玩明日方舟,在这款游戏中干员的时装是使用至纯源石购买的,他想购买一款时装,但是他囊中羞涩,请你帮他算一算他能不能购买这款时装
输入
一行两个整数 x, y ( 0 ≤ x ≤ 1000, 1 ≤ y ≤ 5 ) 其中 x 代表是该沙漠同学拥有的至纯源石,y 表示是该沙漠同学现在想买的时装
当 y = 1 时,是该沙漠同学想买的是干员芬的时装十字郡(售价 0 至纯源石)
当 y = 2 时,是该沙漠同学想买的是干员幽灵鲨的时装暗流(售价 15 至纯源石)
当 y = 3 时,是该沙漠同学想买的是干员琴柳的时装识芳(售价 18 至纯源石)
当 y = 4 时,是该沙漠同学想买的是干员鸿雪的时装字句中的雪原(售价 21 至纯源石)(虽然是该沙漠同学没抽出鸿雪……)
当 y = 5 时,是该沙漠同学想买的是干员异客的时装今昔须臾之梦(售价 24 至纯源石)
输出
先输出一行字符串,其中 "Yes" 代表可以购买,"No" 代表不能购买(不含双引号)
再输出一行一个整数 s ,代表是该沙漠同学能剩下多少至纯源石 / 还需要多少至纯源石才能购买
样例输入 Copy
20 2
样例输出 Copy
Yes
5
提示
样例输入2
15 5
样例输出2
No
9
源代码
//水题
#include <iostream>
using namespace std;
int main()
{
int x,y;
cin >> x >> y;
if(y == 1)
{
cout << "Yes" << endl;
cout << x << endl;
}
else if(y == 2)
{
if(x < 15)
{
cout << "No" << endl;
cout << abs(x - 15) << endl;
}
else
{
cout << "Yes" << endl;
cout << x - 15 << endl;
}
}
else if(y == 3)
{
if(x < 18)
{
cout << "No" << endl;
cout << abs(x - 18) << endl;
}
else
{
cout << "Yes" << endl;
cout << x - 18 << endl;
}
}
else if(y == 4)
{
if(x < 21)
{
cout << "No" << endl;
cout << abs(x - 21) << endl;
}
else
{
cout << "Yes" << endl;
cout << x - 21 << endl;
}
}
else if(y == 5)
{
if(x < 24)
{
cout << "No" << endl;
cout << abs(x - 24) << endl;
}
else
{
cout << "Yes" << endl;
cout << x - 24 << endl;
}
}
return 0;
}
H 菜姬酱最喜欢+1辣!!!
题目描述
菜姬酱天天在 “郑轻23级C语言交流群” 中水群,群里的同学们超喜欢聊天,因此群聊中天天会出现 “+1”。菜姬酱有个习惯,每次见到一句话后面出现 “+1” 后必定会点击20次 “+1”.
现在群聊中突然出现了一句 “ACM,启动!!!”,下一秒满屏都是 “+1”,这时菜姬酱会发送什么呢?
输入
无
输出
输出 20 行 “ACM,启动!!!”
样例输入 Copy
无
样例输出 Copy
ACM,启动!!!
ACM,启动!!!
ACM,启动!!!
... ...
ACM,启动!!!
ACM,启动!!!
ACM,启动!!!
提示
不让坏坏轻易复制粘贴哦~
输出有 20 行捏,看看大家会怎么做呢?
可以用循环解决呦~
源代码
//水题
#include <iostream>
using namespace std;
int main()
{
for(int i = 1;i <= 20;i ++ )
{
cout << "ACM,启动!!!" << endl;
}
return 0;
}
I 混乱的成绩表
题目描述
Zero 是一名学习委员,他负责很多有关学习上的任务,今天辅导员给了他一张成绩单,这个成绩单是按学号排序的,但是它是成绩单,应该按成绩排序。Zero 作为一个 acmer,对排序还算了解,但他想考考你,你能完成这个任务吗?
输入
一个正整数 n,代表成绩单上学生的人数(n <= 2000)
接下来 n 行,每行两个整数 ID 和 x,ID是学生的编号(递增给出),x 是学生成绩 (0 <= x <= 100)
输出
输出按成绩排名的成绩单,成绩越高,排名越靠前,相同成绩的人 ID 较小的排名在前
样例输入 Copy
4
1 68
2 68
3 90
4 91
样例输出 Copy
4 91
3 90
1 68
2 68
源代码
//结构体排序
#include <iostream>
#include <algorithm>//调用sort函数
using namespace std;
struct Student//定义学生结构体
{
int idx;
int score;
};
Student stu[2020];//定义结构体数组
int cmp(Student a,Student b)//自定义cmp函数
{
if(a.score != b.score)return a.score > b.score;
else return a.idx < b.idx;
}
int main()
{
int n;
cin >> n;
for(int i = 1;i <= n;i ++ )cin >> stu[i].idx >> stu[i].score;
sort(stu + 1,stu + 1 + n,cmp);//指定sort排序方式
for(int i = 1;i <= n;i ++ )cout << stu[i].idx << ' ' << stu[i].score << endl;
return 0;
}
转生成为 C 语言糕手——进阶篇
A 复读机!
题目描述
是该沙漠太喜欢水群了!作为 "移动软件 23 级 1-3 班 C 语言课程群" 的管理员,他每天都会点进群里很多次,所以他总是能看到群主朱会东老师发表的一些比较有意思的发言
当然,是该沙漠同学也是很喜欢朱老师说的这些话的,所以,可以把其中任意一句话复述给是该沙漠同学听吗?
输入
无
输出
直接复述朱老师的任意一句完整发言(不含表情包及图片内的文字)
注意段间换行需要全部写进去,段内折行不需要单独换行,判题时忽略行尾换行。
提示
注意换行及标点符号,标点均为中文全角符号
本题仅判定输出的前 2000 个字符的内容,多余内容无效,将会被忽略。
使用 Python 提交时,请在代码最前面加上下面这行代码以防空输出
#! /bin/usr/python2
源代码
//挑一句短的
#include <iostream>
using namespace std;
int main()
{
cout << "年轻人,就是要对自己狠一点" << endl;
return 0;
}
B 运气 or 实力
题目描述
在高中时期,大家肯定是经常做选择题。而在面对选择题的时候,Zero 有两种解决办法给出他的答案:运气 or 实力。
本道题目为选择题,你会如何选择来给出你的答案。
从公元 1001 年到公元 2023 年,一共有多少个闰年?
注意:只需要满足闰年正常的判断标准即可认为是闰年,无需考虑其他因素
输入
无
输出
一个整数,代表闰年的个数
样例输入 Copy
无
样例输出 Copy
240 ~ 250 之间的某个数字
源代码
//水题
//闰年即为要么能被4整除但不能被100整除,要么能被400整除
#include <iostream>
using namespace std;
int main()
{
int ans = 0;
for(int i = 1001;i <= 2023;i ++ )
{
if((i % 4 == 0 && i % 100 != 0) || (i % 400 == 0))ans ++ ;
}
cout << ans << endl;
return 0;
}
C 实力为王
题目描述
不是所有题目都有选项,想要获得胜利,实力为王。
本道题目为填空题,请靠实力说话。
在打竞技类游戏的时候,匹配系统会尽可能给你匹配到旗鼓相当的对手。Zero 认为你已经有这个能力实现这个匹配功能,现在你需要思考如何给玩家匹配水平相近的对手,并且实现它。
输入
第一行一个正整数 n ( n ≤ 3000 )
接下来一行有 n 个正整数 x ( x ≤ 1e9 ),代表 n 个玩家的实力值
最后一行一个正整数 m ( m ≤ 1e9 ),代表实力值为 m 的玩家 Zero 等待匹配
输出
一个整数,代表与 Zero 实力值最为接近的玩家的实力值
如果有实力相差相同的玩家,请输出最早出现的玩家的实力值
样例输入 Copy
10
1 10 100 1000 10000 100000 1000000 10000000 100000000 1000000000
998244353
样例输出 Copy
1000000000
源代码
//注意数据范围,保险起见开long long
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 5050;
ll a[N];
int main()
{
ll n;
cin >> n;
for(int i = 1;i <= n;i ++ )cin >> a[i];
ll m;
cin >> m;
int div = 0x3f3f3f3f,ansidx = -1;//初始化div(差值为极大值),ansidx(答案下标)为-1
for(int i = 1;i <= n;i ++ )
{
ll t = labs(a[i] - m);//fabs为计算浮点数的绝对值
if(t < div)//若当前元素的差值更小
{
div = t;//更新div
ansidx = i;//更新答案下标
}
}
cout << a[ansidx] << endl;
return 0;
}
D 入度和出度 —— 菜姬的算法小课堂
题目描述
菜姬的算法小课堂开课了!!!今天,菜姬老师给大家讲的内容是 "入度和出度"。
"入度和出度" 的定义:节点(顶点)的 入度 是指进入该节点(顶点)的边的条数; 节点(顶点)的 出度 是指从该节点(顶点)出发的边的条数。
"入度和出度" 是图论题面中经常会用到的知识,今天,菜姬老师想带领大家解决一个最基本的问题:"如何统计入度和出度"
要解决这个问题我们还需要先学习一个新概念 "有向边",毕竟图论问题都是以点和边为基础构造的。那么,什么是有向边呢?
"有向边"的定义:有向边是图中的一种边,它具有方向。每条有向边连接两个顶点,并且从一个顶点指向另一个顶点。在有向图中,每条边都是有方向的,因此我们可以将其表示为一个有序对 (u, v),其中 u 是起始点,v 是终端点。
知道了这两个概念,我们也就可以开始解决这个基础的问题了。那么,现在让我们丰富一下题面从而方便大家阅读这个问题吧。
现在这里存在 n 个节点,节点和节点之间可能具有边(有向边),接下来给我们 m 条边,边的形式以有序对 (u, v) 给出。我们需要统计每个点的入度和出度,之后统一输出。
输入
第一行输入两个整数 n, m ( 1 ≤ n, m ≤ 105 )。
接下来 m 行每行给定两个值 u, v ( 1 ≤ u, v ≤ n ) 分别代表端点编号
数据不存在自环
输出
输出 n 行数据,输出每个端点的出度和入度,输出格式如样例。
(若该点无入度或出度请输出数字 0)
样例输入 Copy
5 3
1 2
2 3
3 4
样例输出 Copy
1 0
1 1
1 1
0 1
0 0
提示
对于 (1, 2) 边,该边是由节点 1 到节点 2 的一条有向边,那么点 1 的出度加 1,点 2 的入度加 1。其它边同理。
本题实现方式并不困难,难点在于对新概念的快速学习和理解。编程的学习就是这样,如果你学习吸收新知识新概念的能力很弱,就很难解决很多问题,哪怕这些问题的实现方式其实很简单。当然如果并不理解本题请不要气馁,对于新手来说编程思维和高中时的学习思维还是有很大差距,一时半会儿没转变过来很正常(大家智商其实都大差不差哦),但是请不要放弃,努力培养自己的编程思维是很有必要的,从0到1很难,从1到2就不会那么困难了。所以,加油吧,同学!!!
源代码
//数据结构与算法中有向图的相关概念
#include <iostream>
using namespace std;
const int N = 100000 + 10;
int st[N],ed[N];//st[i]储存的值为第i个节点的出度个数,ed[i]储存的为第i个节点的入度个数
int main()
{
int n,m;
cin >> n >> m;
while(m -- )
{
int a,b;
cin >> a >> b;//建立一条从a指向b的有向边,a为起点,b为终点
st[a] ++ ;//a的出度个数+1
ed[b] ++ ;//b的入度个数+1
}
for(int i = 1;i <= n;i ++ )
{
cout << st[i] << ' ' << ed[i] << endl;
}
return 0;
}
E 菜姬不喜欢排队!!!
题目描述
"天天上课坐电梯排队,去食堂吃饭也要排队,买东西也要排队,怎么大家都这么喜欢排队呀?啊啊啊~菜姬酱实在是受不了一点辣!!!"
众所周知,菜姬特别讨厌排队,而且可爱的菜姬还是个坏东西,特别喜欢对队首的同学发出恶意(菜姬也想排第一个!!!),今天菜姬又又又排上了队,可怜的菜姬再次发出了无能狂怒。
队伍中有 n 位同学(显然不包括菜姬,菜姬肯定是在队伍最后哒~),接下来给出 n - 1 个前后关系,我们以有序对 (u, v) 表示。u 同学在 v 同学后面(挨着的哦),同学的编号属于 [1, n] 且不会重复。显然 n - 1 对有序对能涵盖队伍的所有相邻的前后关系。
聪明的你能回答菜姬到底对队伍里的哪位同学恶意最大吗?
输入
第一行输入一个正整数 n ( 1 ≤ n ≤ 105 ) 表示同学数量
接下来 n - 1 行,每行输入两个数 u, v ( 1 ≤ u, v ≤ n ) 代表相邻同学关系。
输出
输出一个正整数,表示菜姬恶意最大同学的编号。
样例输入 Copy
5
1 2
2 3
3 4
4 5
样例输出 Copy
5
提示
本题可运用 "入度和出度" 知识呦。所以聪明的同学们能想到该怎么解决吗?大家加油哦~(菜姬酱加油助威!!!)
源代码
//n - 1 对有序对能涵盖队伍的所有相邻的前后关系
//故图建立完毕之后,是一条很长的边,类似于单链表
//起点的特性:入度为0
//根据上一题的代码,统计每个点的入度,找到入度为0的点输出即可
#include <iostream>
using namespace std;
const int N = 100000 + 10;
int st[N],ed[N];
int main()
{
int n;
cin >> n;
int cnt = n - 1;
while(cnt -- )
{
int a,b;
cin >> a >> b;
st[a] ++ ;
ed[b] ++ ;
}
for(int i = 1;i <= n;i ++ )
{
if(st[i] == 0)
{
cout << i << endl;
break;
}
}
return 0;
}
F 前缀和 —— 菜姬的算法小课堂
题目描述
菜姬的算法小课堂开课了!!!今天,菜姬老师给大家讲的内容是“前缀和”。
"前缀和" 的定义:数列的前 n 项的和。
前缀和是一种重要的预处理,能大大降低查询的时间复杂度。 我们可以简单理解为 "数列的前 n 项的和"。 这个概念其实很容易理解,即一个前缀和数组中,第 n 位存储的是原数组前 n 个数字的和。
在这里我默认大家对高中的数学基本知识还有印象,那么前缀和以高中学的数列来表示就是
当然,在编程里我们不需要记忆什么求和公式,而且基本上所有前缀和(一维)的求解形式都是一样的。
形式来讲,假如我们有一个长度为 n 的数组 a,数组 a 的每一项都有一个初始值,那么求解这个数组的前缀和方式为:
使用 for 循环从前往后遍历,对于当前下标 x,我们需要进行 a[x] += a[x - 1] 操作,这样循环下来就能取得数组的前缀和数组,通俗来说对于一个初始的数组,如果我们需要求解前缀和数组第 x 项,那么这个第 x 项显然值为原数组 a 的前 x 项和,即我们求解时可以用原数组 a 前 x - 1 项和加上我们 a 数组第 x 项。
当然以上求出的前缀和数组会覆盖原数组 a,如果大家想保留原数组我们可以用新数组 S 代码前缀和数组。同理,求解 S 的方式类似,我们只需要进行 S[x] = S[x - 1] + a[x],需要注意的是 S1 = a1。
总而言之,本节并不是想让大家具体掌握前缀和知识,只是想提前让大家了解一下。因此,我们的问题相对来说会很简单。那么来让我们练练手吧:
假设我们有一个长度为 n 的数组,请求出数组的前缀和数组,并输出每一项。
输入
第一行输入一个 n ( 1 ≤ n ≤ 105 )
接下来有 n 行,每一行输入一个整数 ai
保证
输出
输出 n 行,第 i 行输出前缀和数组第 i 项。
样例输入 Copy
4
1
1
1
1
样例输出 Copy
1
2
3
4
提示
本题实现难度非常简单,前缀和的概念也不是很复杂,如若不懂,可自行百度。
源代码
//题目已给的很明显
#include <iostream>
using namespace std;
const int N = 100000 + 10;
int a[N],s[N];//a为正常数组,s为前缀和数组
int main()
{
int n;
cin >> n;
for(int i = 1;i <= n;i ++ )
{
cin >> a[i];
s[i] = s[i - 1] + a[i];//进行前缀和运算
}
for(int i = 1;i <= n;i ++ )cout << s[i] << endl;
return 0;
}
G 坐地铁!(Easy Version)
题目描述
是该沙漠同学去广州旅游了,当他到达广州南站地铁站的时候,他看着广州错综复杂的地铁网感到了迷茫,请帮他算一下他某一次行程的最低车票支出
下面是广州地铁票务规则中有关票价及日票的部分内容
-
广州地铁线网票价按里程分段计价:
起步 4 公里以内 2 元;
4 至 12 公里范围内每递增 4 公里加 1 元;
12 至 24 公里范围内每递增 6 公里加 1 元;
24 公里以后,每递增 8 公里加 1 元。
-
乘客可在广州地铁线网任一车站购买日票。
一日票:乘客持一日票首次进闸起 24 小时内可不限次数、距离及线路乘坐地铁,每张 20 元。
三日票:乘客持三日票首次进闸起 72 小时内可不限次数、距离及线路乘坐地铁,每张 50 元。
为了简化题目,本题只考虑起点和终点都在同一条线路的情况,不考虑换乘、支线、环线等复杂情况
不考虑通过其他线路可以缩短路程的可能性,不考虑当天后续的行程对当前行程的影响
假定所有行程都能在 24 小时内完成
输入
第一行输入一个整数 n ( 1 ≤ n ≤ 105) ,代表线路上的站点数
第二行输入 n - 1 个实数 a1, a2, a3, ..., an-1 ( ai > 0 ) ,ai 代表区间 i 到 i+1 的距离(其中 i 代表站点编号,单位为公里)
第三行输入一个整数 q (1 ≤ q ≤ 105 ) ,代表查询的次数,每次查询是独立的
接下来 q 行,每行两个整数 x, y ( 1 ≤ x, y ≤ n ) ,分别代表是该沙漠同学某次行程起点和终点的站点编号(不包含前导 0)
输出
输出 q 行,每行一个整数 p,即是该沙漠同学当次行程需要支付的最小金额
样例输入 Copy
8
7.8 25.8 9.3 3.8 5.1 2.1 3.9
5
1 8
2 3
2 8
5 5
7 8
样例输出 Copy
11
7
10
2
2
提示
保证
在地铁票务系统中,不足 x 公里按 x 公里计算(如 5 公里的票价为 3 元)
请使用 double 类型而非 float 类型以避免精度问题
对于 Python 的提交,请使用 sys.stdin 读入,否则可能会时间超限
源代码
//因题目已给出:假定所有行程都能在 24 小时内完成,故只有两种情况,要么单程票,要么一日票,二者取min即可,数据量过大,要使用scanf与printf
#include <iostream>
#include <cmath>//使用ceil向上取整函数
using namespace std;
const int N = 100000 + 10;
double a[N],b[N];//a为原数组,b为前缀和数组
int main()
{
int n;
scanf("%d",&n);
for(int i = 1;i <= n - 1;i ++ )scanf("%lf",&a[i]);
for(int i = 2;i <= n;i ++ )b[i] = b[i - 1] + a[i - 1];
int q;
scanf("%d",&q);
while(q -- )
{
int ans = 0;
int st,ed;
scanf("%d%d",&st,&ed);
double sum = fabs(b[ed] - b[st]);//利用前缀和数组,在O(1)的时间复杂度下,求得区间和
//根据里程计算票价
if(sum <= 4)ans = 2;
else if(sum > 4 && sum <= 12)
{
sum -= 4;
ans = 2;
ans += ceil(sum / 4);
}
else if(sum > 12 && sum <= 24)
{
sum -= 12;
ans = 4;
ans += ceil(sum / 6);
}
else if(sum > 24)
{
sum -= 24;
ans = 6;
ans += ceil(sum / 8);
ans = min(ans,20);
}
printf("%d\n",ans);
}
return 0;
}
H 坐地铁!(Hard Version)
题目描述
请先阅读 "坐地铁!(Easy Version)" 再来作答此题!
是该沙漠同学打算在广州游玩 3 天,他已经规划好 3 天的路线了!为了环(sheng)保(qian),他还是选择搭乘地铁出行
所以乘坐地铁购票的时候有以下几种选择:
-
3 天所有行程购买均单程票
-
其中任意 1 或 2 天购买相应张数一日票,剩余 2 或 1 天购买单程票
-
购买一张三日票
是该沙漠同学不会算数,但是他又想选择一种最省钱的方案,这复杂的计算可把他给绕晕了捏
为了简化问题,我们规定单日票次日 0 点自动失效,第二天不可继续使用
计费规则同 "坐地铁!(Easy Version)" ,故本题不再赘述
输入
第一行输入一个整数 n ( 1 ≤ n ≤ 105 ) ,代表线路上的站点数
第二行输入 n - 1 个实数 a1, a2, a3, ..., an-1 ( ai > 0 ) ,ai 代表区间 i 到 i+1 的距离(其中 i 代表站点编号,单位为公里)
第三行输入三个整数 t1, t2, t3 ( t1, t2, t3 ≥ 0 且 t1 + t2 + t3 ≤ 105 ) ,分别代表是该沙漠同学每天要搭乘几次地铁
接下来 t1 行,每行两个整数 x, y ( 1 ≤ x, y ≤ n ) ,分别代表是该沙漠同学第 1 天某次行程起点和终点的站点编号
接下来 t2 行,每行两个整数 x, y ( 1 ≤ x, y ≤ n ) ,分别代表是该沙漠同学第 2 天某次行程起点和终点的站点编号
接下来 t3 行,每行两个整数 x, y ( 1 ≤ x, y ≤ n ) ,分别代表是该沙漠同学第 3 天某次行程起点和终点的站点编号
所有站点编号均不包含前导 0
输出
如果是该沙漠同学三天都没出门(即三天都没有行程),请输出 "Lazy, SkySummer!" 3 遍(每次一行,不含引号)
否则输出一行一个整数 p,即是该沙漠同学这 3 天搭乘地铁的最低车票支出
样例输入 Copy
5
1.2 1.2 1.2 1.2
1 1 1
1 2
2 3
3 4
样例输出 Copy
6
提示
请注意输入格式!
保证
保证全部行程的单程票票价总和不超过 10e10
源代码
//与上一题类似,不过是将计算每次单程票的程序块封装成了一个函数便于使用
#include <iostream>
#include <cmath>//调用ceil函数
#include <vector>//使用动态数组
#include <algorithm>//调用sort函数
using namespace std;
const int N = 100000 + 10;
double a[N],b[N];
//定义函数,计算从st到ed的单程票费用
int fun(int st,int ed)
{
int ans = 0;
double sum = fabs(b[ed] - b[st]);
if(sum <= 4)ans = 2;
else if(sum > 4 && sum <= 12)
{
sum -= 4;
ans = 2;
ans += ceil(sum / 4);
}
else if(sum > 12 && sum <= 24)
{
sum -= 12;
ans = 4;
ans += ceil(sum / 6);
}
else if(sum > 24)
{
sum -= 24;
ans = 6;
ans += ceil(sum / 8);
ans = min(ans,20);
}
return ans;
}
int main()
{
int n;
scanf("%d",&n);
for(int i = 1;i <= n - 1;i ++ )scanf("%lf",&a[i]);
for(int i = 2;i <= n;i ++ )b[i] = b[i - 1] + a[i - 1];//前缀和处理
int t1,t2,t3;
scanf("%d%d%d",&t1,&t2,&t3);
if(t1 == 0 && t2 == 0 && t3 == 0)//若是没动,就是懒蛋
{
for(int i = 1;i <= 3;i ++ )printf("Lazy, SkySummer!\n");
}
else
{
int ans1 = 0,ans2 = 0,ans3 = 0;
while(t1 -- )
{
int st,ed;
scanf("%d%d",&st,&ed);
ans1 += fun(st,ed);
}
//计算第一天的单程票总价
while(t2 -- )
{
int st,ed;
scanf("%d%d",&st,&ed);
ans2 += fun(st,ed);
}
//计算第二天的单程票总价
while(t3 -- )
{
int st,ed;
scanf("%d%d",&st,&ed);
ans3 += fun(st,ed);
}
//计算第三天的单程票总价
vector<int> ans;
//三天都是单程票
ans.push_back(ans1 + ans2 + ans3);
//一天是单程票,其余两天是一日票
ans.push_back(20 + ans2 + ans3);
ans.push_back(ans1 + 20 + ans3);
ans.push_back(ans1 + ans2 + 20);
//两天都是单程票,其余一天是一日票
ans.push_back(20 + 20 + ans3);
ans.push_back(ans1 + 20 + 20);
ans.push_back(20 + ans2 + 20);
//直接买三日票
ans.push_back(50);
//按票价从小到大排序
sort(ans.begin(),ans.end());
//最小的即在开头,输出即可
printf("%d\n",ans[0]);
}
return 0;
}
I 女巫的魔法
题目描述
在魔法世界,Zero 碰到了一名女巫,她可以施展魔法让被施法者变得强大,Zero 想要变得强大,所以他准备给女王送一些糖果来获得女巫的帮助,假设 Zero 有数不尽的糖果,而 Zero 并不知道送多少糖果女巫会满意,所以他选择第一次送 1 糖果,第二次送 2 个糖果,···, 第 n 次送 n 个糖果,直到女巫满意为止,假设你得知了女巫至少得到多少糖果就会满意,请你告诉 Zero 他至少需要送几次糖果女巫才会愿意为他施展魔法。
输入
一个正整数 x,代表女巫至少需要 x 个糖果就会满意 ( x <= 1e18 )
输出
一个整数 y,代表 Zero 至少需要送 y 次糖果
样例输入 Copy
5
样例输出 Copy
3
提示
样例解释:女巫需要 5 个糖果,前 3 次 Zero 分别送了 1, 2, 3 个糖果,一共送了 6 个,满足 6 >= 5,所以需要送 3 次女巫才会满足(可以证明送糖果的次数小于 3 次时不满足条件)
源代码
//数据范围为1e18,要开long long
#include <iostream>
using namespace std;
typedef long long ll;
int main()
{
ll x;
cin >> x;
ll sum = 0,ans = 0,idx = 1;//sum为目前的累加和,ans为累加次数,idx为累加权值
while(sum < x)
{
ans ++ ;//累加次数+1
sum += idx;//进行累加
idx ++ ;//权值+1
}
cout << ans << endl;
return 0;
}