1.快速公交BRT
【问题描述】
在城市里,快速公交(BRT)线路为一条直线,在其线路上有 n 个交叉路口,在每个路口都有一个交通信号灯,在红灯与绿灯之间周期性循环。
在绿灯亮起持续 g 秒的期间,允许通行,之后变为红灯,保持 r 秒,红灯期间禁止车辆通行。如果一辆车正好在变为红灯的时候到达交叉口,它应该停车,但是如果是正好变成绿灯,车辆就可以继续行驶。
所有的交通灯都有相同的变化时间,并且是同步的。换句话说,对于所有的交通灯来说,红灯(和绿灯)的相位是相同的,它们都在第 0 时刻开始变为绿色。
BRT公司已经设计好了公交车通过每个路段的时间,路段是指两个连续的交通灯之间的距离,或者是起点与第一个交通灯的距离,或者是最后一个交通灯与终点的距离,更精确地讲,BRT专家设计了 n + 1 个正整数 li,时间以秒计,表示公交车从起点到终点时穿过第 i 路段的时间,l1 为从起点到第一个路口的时间, ln+1 表示从最后一个路口·到终点的时间。
在一天内有 q 辆公交车离开起点,第 i 辆车在时刻 ti(以秒计)出发,公司管理者想知道公交车在什么时间可以到达终点。
【输入形式】
输入的第一行为三个整数 n、g、r,分别表示交叉路口的个数,绿灯持续的时间和红灯持续的时间。
接下来一行为 n + 1 整数 li , i =1, ..., n + 1,表示公交车通过第 i 个路段的时间。
接下来的一行为单一的一个整数 q,表示一天内从起点出发的公交车数量,接下来的一行为 q 个整数,表示每辆公交车离开起点的时间。
【输出形式】
输出为一行 q 个整数,分别表示每辆公交车到达终点的时间。
【样例输入】
1 3 2 5 2 5 1 2 3 4 5
【样例输出】
8 9 12 12 12
// 快速公交BRT
// 在城市里,快速公交(BRT)线路为一条直线,在其线路上有 n 个交叉路口,在每个路口都有一个交通信号灯,在红灯与绿灯之间周期性循环。
//
// 在绿灯亮起持续 g 秒的期间,允许通行,之后变为红灯,保持 r 秒,红灯期间禁止车辆通行。如果一辆车正好在变为红灯的时候到达交叉口,它应该停车,但是如果是正好变成绿灯,车辆就可以继续行驶。
//
// 所有的交通灯都有相同的变化时间,并且是同步的。换句话说,对于所有的交通灯来说,红灯(和绿灯)的相位是相同的,它们都在第 0 时刻开始变为绿色。
//
// BRT公司已经设计好了公交车通过每个路段的时间,路段是指两个连续的交通灯之间的距离,或者是起点与第一个交通灯的距离,或者是最后一个交通灯与终点的距离,更精确地讲,BRT专家设计了 n + 1 个正整数 li,时间以秒计,表示公交车从起点到终点时穿过第 i 路段的时间,l1 为从起点到第一个路口的时间, ln+1 表示从最后一个路口·到终点的时间。
//
// 在一天内有 q 辆公交车离开起点,第 i 辆车在时刻 ti(以秒计)出发,公司管理者想知道公交车在什么时间可以到达终点。
#include<iostream>
using namespace std;
int main()
{
int n,g,r,m;
cin>>n>>g>>r;
int *l=new int[n+1];
for(int i=0;i<n+1;i++){
cin>>l[i];
}
cin>>m;
int *q=new int[m];
for(int i=0;i<m;i++){
cin>>q[i];
}
for(int i=0;i<m;i++){
int tem=q[i]; //记录当前时刻
for(int j=0;j<n;j++){
tem+=l[j]; //通过路段时间
if(tem%(g+r)<g){
tem=tem;//绿灯可以直接通行
}else{
tem+=(g+r-tem%(g+r)); //红灯要等待
}
}
tem+=l[n]; //最后一段直接加
cout<<tem<<" ";
}
return 0;
}
2.松雅的新旅馆
【问题描述】
松雅终于确定了新建旅馆的城市,她看中了该城市临海一条笔直的街道,此处风景优美,街道另一边是海滩,不允许有任何建筑。
不妨将该街道视作为一条坐标轴(x-轴),街道上已有 n 座方形建筑,它们的边平行于 x 轴,其中的一条横边的位于坐标轴上,其中心点为整数坐标。这些房子不会交叠,但可以相互挨着。
松雅所建的旅馆的横边长为 t,并且至少与一座已有的建筑相互挨着,这样她可以节省一些建设费用,当然,这座建筑的一条横边必须位于 x 轴上,房子不能交叠。
给出所有已有的建筑的中心点和横边长(忽略建筑墙体的厚度),请你帮她找出可以新建旅馆的位置有多少?
【输入形式】
输入的第一行为两个正整数 n 和 t( n、t ≤ 1000),分别该街道上已有的建筑数量以及她所建旅馆的横边长。
接下来的 n 行,每行两个整数 xi 和 ai,分别表示每座已有建筑位于坐标轴上的横边的中心点和横边长,其中,-20000 ≤ xi ≤20000,1≤ ai ≤1000。
【输出形式】
请输出可以新建旅馆的可能的位置的数量。
【样例输入1】
2 2 0 4 6 2
【样例输出1】
4
【样例输入2】
2 2 0 4 5 2
【样例输出2】
3
【样例输入3】
2 3 0 4 5 2
【样例输出3】
2
【样例说明】
注意,新建房子的中心坐标可能为非整数,输入的相邻xi 之间的大小关系不确定。
松雅的新旅馆
//松雅终于确定了新建旅馆的城市,她看中了该城市临海一条笔直的街道,此处风景优美,街道另一边是海滩,不允许有任何建筑。
//
// 不妨将该街道视作为一条坐标轴(x-轴),街道上已有 n 座方形建筑,它们的边平行于 x 轴,其中的一条横边的位于坐标轴上,其中心点为整数坐标。这些房子不会交叠,但可以相互挨着。
//
// 松雅所建的旅馆的横边长为 t,并且至少与一座已有的建筑相互挨着,这样她可以节省一些建设费用,当然,这座建筑的一条横边必须位于 x 轴上,房子不能交叠。
//
// 给出所有已有的建筑的中心点和横边长(忽略建筑墙体的厚度),请你帮她找出可以新建旅馆的位置有多少?
//
//【输入形式】
//
// 输入的第一行为两个正整数 n 和 t( n、t ≤ 1000),分别该街道上已有的建筑数量以及她所建旅馆的横边长。
//
// 接下来的 n 行,每行两个整数 xi 和 ai,分别表示每座已有建筑位于坐标轴上的横边的中心点和横边长,其中,-20000 ≤ xi ≤20000,1≤ ai ≤1000。
#include<iostream>
using namespace std;
int main()
{
int n,t,c=0;
cin>>n>>t;
int *x=new int[n];
int *a=new int[n];
for(int i=0;i<n;i++){
cin>>x[i]>>a[i];
}
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(x[i]>x[j]){
int t1=x[i];
int t2=a[i];
x[i]=x[j];
x[j]=t1;
a[i]=a[j];
a[j]=t2; //排序
}
}
}
for(int i=0;i<n-1;i++){
if((x[i+1]-x[i]-a[i+1]/2.0-a[i]/2.0)>t){
c+=2;//两个位置
}else if((x[i+1]-x[i]-a[i+1]/2.0-a[i]/2.0)==t){
c+=1;//1个位置
}
}
cout<<c+2<<endl; //左右两边肯定可以
return 0;
}
3.激光与巧克力
【问题描述】
在一家重要的研究机构工作,小希参与了一项重要的试验:使用激光装置融化巧克力。
该装置有包含 n×m 个单元的一个长方形区域以及一个机械臂组成,每个单元为一个 1×1 的小方块。机械臂上有两束激光垂直射向其表面,任何时候激光束都会射向两个单元的中心。由于两个激光束发射装置装在同一个机械臂上,故移动是同步的,也就是说,移动都在同一方向上。
已知的事实为:
-
-
开始时整个区域被大小为 n×m 的巧克力块覆盖,两束激光均处于区域上方且已激活
-
只有被激光射向单元的巧克力将融化,其他单元内的不受影响
-
机械臂的任何移动必须平行于区域的边缘,每次移动后激光都会同时射向两个单元的中心
-
任何时候激光都只能射向本区域
-
给出 n 和 m,表示区域的大小,行号从上往下从 1 到 n,列号从左到右为 1 到 m。
给出两束激光最开始时的位置 (x1, y1) 和 (x2, y2),其中 x1、x2 为行号,y1、y2 为列号。
请找出这个区域内有多少单元的巧克力不能被融化。
【输入形式】
输入的第一行为一个正整数 t,表示测试数据的组数。
接下来的 t 每行6个正整数 n、m、x1、y1、x2、y2 (2 ≤ n, m ≤ 109, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),分别表示区域的行数和列数,以及开始时激光束所在的位置。
【输出形式】
输出的t行,每行对应每组测试用例的结果
【样例输入】
2 4 4 1 1 3 3 4 3 1 1 2 2
【样例输出】
8 2
//激光与巧克力
//在一家重要的研究机构工作,小希参与了一项重要的试验:使用激光装置融化巧克力。
//
// 该装置有包含 n×m 个单元的一个长方形区域以及一个机械臂组成,每个单元为一个 1×1 的小方块。机械臂上有两束激光垂直射向其表面,任何时候激光束都会射向两个单元的中心。由于两个激光束发射装置装在同一个机械臂上,故移动是同步的,也就是说,移动都在同一方向上。
//
// 已知的事实为:
//
//开始时整个区域被大小为 n×m 的巧克力块覆盖,两束激光均处于区域上方且已激活
//
//只有被激光射向单元的巧克力将融化,其他单元内的不受影响
//
//机械臂的任何移动必须平行于区域的边缘,每次移动后激光都会同时射向两个单元的中心
//
//任何时候激光都只能射向本区域
//
// 给出 n 和 m,表示区域的大小,行号从上往下从 1 到 n,列号从左到右为 1 到 m。
//
// 给出两束激光最开始时的位置 (x1, y1) 和 (x2, y2),其中 x1、x2 为行号,y1、y2 为列号。
//
// 请找出这个区域内有多少单元的巧克力不能被融化。
#include<iostream>
using namespace std;
int main()
{
int t,n,m,x1,y1,x2,y2;
cin>>t;
while(t--){
cin>>n>>m>>x1>>y1>>x2>>y2;
int res=n*m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){ //遍历所有位置,看能不能到达这个位置
if(((i-x1+x2)>0&&(i-x1+x2)<=n && (j-y1+y2)>0 && (j-y1+y2)<=m) || ((i-x2+x1)>0&&(i-x2+x1)<=n && (j-y2+y1)>0 && (j-y2+y1)<=m)){
res-=1;//可以到达
}
}
}
cout<<res<<endl;
}
return 0;
}
4.小希的新工作
【问题描述】
小希最近找到了大公司的客户经理的新工作,每天工作时间为 L 分钟,他主要为 n 个固定的高端客人服务,第 i 个客人会在第 ti 分钟到来,他需要为其服务 li 分钟,在此期间不会有其他客人到来。
他喜欢在工作的间隙放松一下,喝杯咖啡,或者做做简单的运动,每次需要 a 分钟的时间,如果可以,这样惬意的事情他能够连续做好多次。但在有顾客的时间里,他必须在工作岗位上,否则,他会被投诉。那么,在一天的工作时间之内,他最多有几次这样轻松的时光?
【输入形式】
输入的第一行包含3个整数 n、L 和 a。
接下来的 n 行,每行两个整数 ti 和 li,分别表示第i个客人到来的时间和需要服务的时间,输入保证 ti+li ≤ ti+1
【输出形式】
输出为一个整数,表示小希在一天的工作时间内最多可以放松多少次?
【样例输入】
2 11 3 0 1 1 1
【样例输出】
3
//小希的新工作
// 小希最近找到了大公司的客户经理的新工作,每
//天工作时间为 L 分钟,他主要为 n 个固定的高端客人服务,第 i 个客人会在第 ti 分钟到来,
//他需要为其服务 li 分钟,在此期间不会有其他客人到来。
//
// 他喜欢在工作的间隙放松一下,喝杯咖啡,或者做做简单的运动,
// 每次需要 a 分钟的时间,如果可以,这样惬意的事情他能够连续做好多次。
// 但在有顾客的时间里,他必须在工作岗位上,否则,他会被投诉。那么,在一天的工作时间之内,他最多有几次这样轻松的时光?
#include<iostream>
using namespace std;
int main()
{
int n,L,a,res=0;
cin>>n>>L>>a;
int *t=new int[n];
int *l=new int[n];
for(int i=0;i<n;i++){
cin>>t[i]>>l[i];
}
int now=0; //记录当前时间
for(int i=0;i<n;i++){
res+=(t[i]-now)/a; //开始工作前可以休息的次数
now=t[i]+l[i]; //当前时间改变
if(i==n-1){
res+=(L-now)/a; //工作完成后,剩余时间可以休息的次数
}
}
cout<<res<<endl;
return 0;
}
5.排队喝水
【问题描述】
某班有 n 个学生,下课铃一响,大家都去饮水机喝水,没有两个人能同时使用饮水机,因此,同学们必须排队取水。
第 i 个学生在第 li 秒来到队尾,如果同一时刻有多个学生来到队伍,则编号大的排在编号小的后面,排在队伍最前面的学生将花1秒的时间取水,然后离开,其他人在后面排队。如果到第 ri 秒学生 i 还没有取到水且他前面还有人,他将不打水而直接离开队伍。
编程求每个学生取到水的时间。
【输入形式】
输入第一行为一个整数T,表示测试用例的个数。
接下来是T个测试用例,每个用例的第一行为一个整数 n,表示学生数,接下来的 n 行,每行两个整数 li 和 ri ,分别表示第 i 个同学在第 li 秒来到队伍末尾,如果第 ri 秒还没取到水则离开队伍的时间。
【输出形式】
对于每个测试用例,输出 n 个整数,表示第 i 个学生取到水的秒数,如果没取到水则为0
【样例输入】
2 2 1 3 1 4 3 1 5 1 1 2 3
【样例输出】
1 2 1 0 2
//排队喝水
//某班有 n 个学生,下课铃一响,大家都去饮水机喝水,没有两个人能同时使用饮水机,因此,同学们必须排队取水。
//
// 第 i 个学生在第 li 秒来到队尾,如果同一时刻有多个学生来到队伍,则编号大的排在编号小的后面,排在队伍最前面的学生将花1秒的时间取水,然后离开,其他人在后面排队。如果到第 ri 秒学生 i 还没有取到水且他前面还有人,他将不打水而直接离开队伍。
//
// 编程求每个学生取到水的时间。
#include<iostream>
using namespace std;
int main()
{
int T,n;
cin>>T;
while(T--){
cin>>n;
int *l=new int[n];
int *r=new int[n];
for(int i=0;i<n;i++){
cin>>l[i]>>r[i];
}
int now=0; //记录当前时刻
for(int i=0;i<n;i++){
if(now<=l[i]){
cout<<l[i]<<" ";
now=l[i]+1;
}else if(now>l[i] && now<=r[i]){
cout<<now<<" ";
now=now+1; //可以取到水
}else{
cout<<0<<" "; //取不到水
}
}
cout<<'\n';
}
}
6.阿迪看医生
【问题描述】
这几天同学们总是对阿迪议论纷纷,这使得他很烦恼,似乎产生了一些抑郁,头也有点痛,打不起精神,他只好去看医生。然而,他只有去看过 n 个医生之后才能确诊病情,每个医生都需要上一个医生的诊断结果,因此他必须按顺序去预约每个医生,也就是说,他必须先去看医生1,然后再去看医生2,然后是医生3,等等。只有到最后一个医生那里才能确诊,且每天只能看一个医生。
从今天开始,每个医生都有一个固定的出诊安排表,医生 i 在第 si 天看病人,然后在之后的每个第 di 天看诊。因此,他只在 si、si+di、si+2di、... 这些天工作。
预约每个医生有些困难,他想知道看完所有医生至少需要多少天?
【输入形式】
输入的第一行一个正整数 n ,表示医生的数量。
接下来的 n 行,每行两个正整数 si 和 di,表示第 i 个医生的工作情况。
【输出形式】
输出一行一个整数,表示阿迪看完最后一个医生的天数。
【样例输入】
3 2 2 1 2 2 2
【样例输出】
4
【样例说明】
第1位医生从第2天开始看病,然后在第4、6、8...天看诊
第2位医生从第1天开始看病,然后在第3、5、7...天看诊
第3位医生从第2天开始看病,然后在第4、6、8...天看诊
因此,阿迪可以在第2天去看第1位医生,然后在第3天去看第2位医生,第4天看第3位医生。
//阿迪看医生
// 这几天同学们总是对阿迪议论纷纷,这使得他很烦恼,似乎产生了一些抑郁,头也有点痛,打不起精神,他只好去看医生。然而,他只有去看过 n 个医生之后才能确诊病情,每个医生都需要上一个医生的诊断结果,因此他必须按顺序去预约每个医生,也就是说,他必须先去看医生1,然后再去看医生2,然后是医生3,等等。只有到最后一个医生那里才能确诊,且每天只能看一个医生。
//
// 从今天开始,每个医生都有一个固定的出诊安排表,医生 i 在第 si 天看病人,然后在之后的每个第 di 天看诊。因此,他只在 si、si+di、si+2di、... 这些天工作。
//
// 预约每个医生有些困难,他想知道看完所有医生至少需要多少天?
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int *s=new int[n];
int *d=new int[n];
for(int i=0;i<n;i++){
cin>>s[i]>>d[i];
}
int day=1; //记录第几天
for(int i=0;i<n;i++){
if(i==0){
day=s[i]; //第一位医生
}else{
if(day<s[i]){
day=s[i];
}else{
day++; //看完后要第二天再看
while((day-s[i])%d[i]!=0){
day++; //找到可以看医生的天
}
}
}
}
cout<<day<<endl;
return 0;
}
7.松雅的花园
【问题描述】
冬天到了,松雅觉得是时候给她的花园浇水了。
她的花园由 n 个连续的苗圃组成,编号从 1~n。其中的 k 个苗圃安装有水龙头(第 i 个水龙头位于苗圃 xi),当水龙头打开的时候,可以同时给相邻的苗圃浇水。1个时间单位后,她可以给苗圃 xi 浇好水,2个时间单位后,她可以给 [xi-1, xi+1] 范围内的苗圃(如果有)浇好水,在 j 个时间单位后,她可以给[xi-(j-1),xi+(j-1)]内的苗圃(如果有)浇好水。
图中白色表示该苗圃没有水龙头,红色表示该苗圃有一个水龙头
水龙头打开2个时间单位后,白色部分表示没有浇到水的苗圃,蓝色部分表示已浇水的苗圃
松雅希望在同一时刻打开所有水龙头,她想知道,最少到多少个时间单位以后整个花园都能浇好水。
【输入形式】
第一行一个整数表示测试数据的组数。
接下来T组测试数据 ,每组数据的第一行包含两个整数 n 和 k,分别表示她的花园中的苗圃数和水龙头数,接下来的一行为 k 个整数 xi,表示第 i 个水龙头所在的位置,输入保证对于每个 i >=2,xi - 1 < xi 。
本题只考虑整数单位时间。
【输出形式】
对于每个测试用例,每个用例输出一行一个整数,表示所有水龙头同时打开后整个花园浇好水所需要的最小时间单位数。
【样例输入】
3 5 1 3 3 3 1 2 3 4 1 1
【样例输出】
3 1 4
//松雅的花园
//冬天到了,松雅觉得是时候给她的花园浇水了。
//
// 她的花园由 n 个连续的苗圃组成,编号从 1~n。其中的 k 个苗圃安装有水龙头(第 i 个水龙头位于苗圃 xi),当水龙头打开的时候,可以同时给相邻的苗圃浇水。1个时间单位后,她可以给苗圃 xi 浇好水,2个时间单位后,她可以给 [xi-1, xi+1] 范围内的苗圃(如果有)浇好水,在 j 个时间单位后,她可以给[xi-(j-1),xi+(j-1)]内的苗圃(如果有)浇好水。
//
//
//图中白色表示该苗圃没有水龙头,红色表示该苗圃有一个水龙头
//
//
//水龙头打开2个时间单位后,白色部分表示没有浇到水的苗圃,蓝色部分表示已浇水的苗圃
//
// 松雅希望在同一时刻打开所有水龙头,她想知道,最少到多少个时间单位以后整个花园都能浇好水。
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int t,n,k;
cin>>t;
while(t--){
cin>>n>>k;
int res=0,tem;
int *x=new int[k];
for(int i=0;i<k;i++){
cin>>x[i];
}
if(k>1){
res=max(x[0],n-x[k-1]+1); //两个边界情况
}else{
res=max(x[0],n-x[0]+1);
}
for(int i=0;i<k-1;i++){
if((x[i+1]-x[i])%2==0){
//相距为偶数
tem= (x[i+1]-x[i]+1)/2+1; //浇水完两个水龙头之间
}else{
//相距为奇数
tem= (x[i+1]-x[i]+1)/2; //两个水龙头同时开始浇水
}
res=max(res,tem);
}
cout<<res<<endl;
}
return 0;
}
8.拜访朋友
【问题描述】
小希想去拜访一位朋友,他家位于坐标轴的0点,他朋友的家在坐标点 m(m>0)。
在这条线路上有多路公交车通行,运行区间位于[x,y]之间,x、y为整数,在该区间内的任意整数点都设有公交站,小希可以在任意站上下。
请编程确定小希是否可以搭乘公交车到达朋友家。
【输入形式】
输入第1行为两个正整数 n 和 m,表示公交车的线路数以及小希朋友家的位置。
接下来的 n 行,每行两个整数a、b,表示每路公交车的起点和终点,输入保证a<b且b<100000000。
【输出形式】
输出Yes或No,表示小希是否能搭乘公交去拜访朋友。
【样例输入】
3 5 0 2 2 4 3 5
【样例输出】
Yes
【样例说明】
样例中,小希可以从0(家)坐公交车到达2,然后坐公交到3,再从3到5(朋友家)。
//拜访朋友
//小希想去拜访一位朋友,他家位于坐标轴的0点,他朋友的家在坐标点 m(m>0)。
//
// 在这条线路上有多路公交车通行,运行区间位于[x,y]之间,x、y为整数,在该区间内的任意整数点都设有公交站,小希可以在任意站上下。
//
// 请编程确定小希是否可以搭乘公交车到达朋友家。
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
int *a=new int[n];
int *b=new int[n];
int k=0; //记录最大值右边界
int t=0; //记录当前能到的最远位置
for(int i=0;i<n;i++){
cin>>a[i]>>b[i];
}
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(a[i]>a[j]){
int t1=a[i];
int t2=b[i];
a[i]=a[j];
b[i]=b[j];
a[j]=t1;
b[j]=t2; //排序
}
}
k=max(k,b[i]);
}
if(a[0]<=0 && k>=m){
bool f=true;
for(int i=1;i<n;i++){
t=max(t,b[i-1]);
if( a[i]<=t ){
continue; //看能不能坐到这个地方
}else{
f=false; //没法
break;
}
}
if(f){
cout<<"Yes"<<endl;
}else{
cout<<"No"<<endl;
}
}else{
cout<<"No";
}
return 0;
}
10.小女孩与楼梯
【问题描述】
小女孩塔雅在一栋多层建筑中攀爬楼梯,每次爬过一个楼梯,她喜欢从1到顶数楼梯的台阶级数,并大声地说出每个数字。如果她爬了两个楼梯,第一个有3级,第二个有4级,她将读出数字1、2、3、1、2、3、4。
给出塔雅读出的所有数字,判断她爬了多少楼梯,且输出每个楼梯有多少台阶级数?
【输入形式】
输出的第一行为一个整数n,表示塔雅读出了多少个数字。
第二行包含n个整数a1、a2、...、an,表示塔雅攀爬楼梯时读出的数字,按顺序从第1个到最后一个,当攀爬一个有x级的楼梯时,她将依次读出1、2、...、x。
【输出形式】
输出的第一行一个t,表示塔雅攀爬的楼梯个数,第二行输出t个数,表示每个楼梯的台阶数。
【样例输入】
7 1 2 3 1 2 3 4
【样例输出】
2 3 4
//小女孩与楼梯
//小女孩塔雅在一栋多层建筑中攀爬楼梯,每次爬过一个楼梯,她喜欢从1到顶数楼梯的台阶级数,并大声地说出每个数字。如果她爬了两个楼梯,第一个有3级,第二个有4级,她将读出数字1、2、3、1、2、3、4。
//
// 给出塔雅读出的所有数字,判断她爬了多少楼梯,且输出每个楼梯有多少台阶级数?
#include<iostream>
using namespace std;
int main(){
int n;
cin>>n;
int *a=new int[n];
int *b=new int[n];
for(int i=0;i<n;i++){
cin>>a[i];
b[i]=0;//初始化
}
int c=0;
for(int i=0;i<n;i++){
if((a[i]==1) && i!=0){
b[c]=a[i-1]; //遇到新的一阶
c+=1;
}
if(a[i]==1 && i==(n-1)){
b[c]=1;
c+=1 ;//特殊情况
}else if(i==(n-1)){
b[c]=a[i]; //结尾
c+=1;
}
}
cout<<c<<endl;
for(int i=0;i<n;i++){
if(b[i]==0){
break;
}
cout<<b[i]<<" ";
}
}
11.小希与火车
【问题描述】
春节期间小希计划乘坐火车去旅行。开始时,火车位于位置1,目的地在位置L。火车的速度是1单位长度/分钟(也就是第1分钟火车在位置1,第2分钟在位置2,等等)。
中国人过年都喜欢挂灯笼,在该路线上就有许多灯笼,它们位于能被 v 整除的位置上(也就是说,第1个灯笼在位置 v ,第2个灯笼在位置2v,等等)。
有另外一辆火车停留在从位置 l 到 r 的地方。
显然,当 p 能被 v 整除的时候,且该处没有火车停留(p∉[l;r]),小希就可以看到处于位置 p 上的灯笼。因此,灯笼的位置如果被停留的火车遮挡,小希就看不见这些灯笼。
请输出小希在旅行期间能看到的灯笼数。
【输入形式】
输入的第一行为一个整数T,表示测试数据的组数。
接下来的T行,每行4个整数,为L、v、l、r,分别表示目的地的位置、灯笼的间距、停留火车的位置区间段。
【输出形式】
输出为T行,对应每个测试用例的输出结果。
【样例输入】
4 10 2 3 7 100 51 51 51 1234 1 100 199 1000000000 1 1 1000000000
【样例输出】
3 0 1134 0
//小希与火车
//春节期间小希计划乘坐火车去旅行。开始时,火车位于位置1,目的地在位置L。火车的速度是1单位长度/分钟(也就是第1分钟火车在位置1,第2分钟在位置2,等等)。
//
// 中国人过年都喜欢挂灯笼,在该路线上就有许多灯笼,它们位于能被 v 整除的位置上(也就是说,第1个灯笼在位置 v ,第2个灯笼在位置2v,等等)。
//
// 有另外一辆火车停留在从位置 l 到 r 的地方。
//
// 显然,当 p 能被 v 整除的时候,且该处没有火车停留(p?[l;r]),小希就可以看到处于位置 p 上的灯笼。因此,灯笼的位置如果被停留的火车遮挡,小希就看不见这些灯笼。
//
// 请输出小希在旅行期间能看到的灯笼数。
#include <iostream>
using namespace std;
int main()
{
int T,L,v,l,r;
cin>>T;
while(T--){
cin>>L>>v>>l>>r;
int res=0;
for(int i=1;i<=L;i++){
if(i%v==0 &&((i>r)||(i<l))){ //判断能不能看到灯笼
res++;
}
}
cout<<res<<endl;
}
return 0;
}
13.月历
【问题描述】
输入年份和月份, 输出该月的月历。
【输入形式】
输入包含两个整数Y(Y>1920)和M(1<=M<=12),分别表示年份和月份
【输出形式】
阵列式月历,数字间用空格分隔。
【样例输入】
2016 11
【样例输出】
【样例说明】
输出格式严格参照样例输出
//月历
//输入年份和月份, 输出该月的月历。
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int y,m,s=0;
cin>>y>>m;
for(int i=1921;i<y;i++){
if(i%400==0||(i%100!=0&&i%4==0)){
s+=366;
}else{
s+=365;
}
}
for(int i=1;i<m;i++){
if(i==2){
if(y%400==0||(y%100!=0&&y%4==0)){
s+=29;
}
else{
s+=28; //s记录总天数,用来求星期
}
}
else if(i==1 || i==3 || i==5 || i==7 || i==8 || i==10 || i==12){
s+=31;
}else{
s+=30;
}
}
int x=(s+6)%7; //获得星期数
int t=0; //当前月份天数
cout<<setw(4) <<"Sun"<<setw(4)
<<"Mon"<<setw(4)
<<"Tus"<<setw(4)
<<"Wed"<<setw(4)
<<"Thu"<<setw(4)
<<"Fri"<<setw(4)
<<"Sat"<<endl;
if(m==1 || m==3 || m==5 || m==7 || m==8 || m==10 || m==12){
t=31;
}else if(m==2){
if(y%400==0||(y%100!=0&&y%4==0)){
t=29; //判断月份天数
}
else{
t=28;
}
}else{
t=30;
}
for(int i=0;i<x;i++){
cout<<" "; //最前面的空格
}
for(int i=1;i<=t;i++){
if((i+x)%7==0){
cout<<setw(4)<<i<<endl; //换行
}else{
cout<<setw(4)<<i;
}
}
return 0;
}
14.松雅旅馆的自动门
【问题描述】
松雅的旅馆门口有一个自动门,按照以下方式工作:
-
-
当门是关闭的时候,1或多个人来到门前,门将马上自动打开,所有人都能马上入内;
-
当门是打开的时候,1或多个人来到门前,所有人都能马上入内;
-
打开的门在打开后的 d 秒钟内立即关闭;
-
当门正在关闭时,1或多个人在同一时刻来到门前,所有人有足够时间入内,之后才会关闭
-
例如,如果 d=3,有4人在4个不同时刻t1=4、t2=7、t3=9 和 t4=13 来到门前,门将会打开3次,即在时刻4、9和13打开,在时刻7和12关闭。
已知有 n 个员工将在 a、2*a、3*a、...、n*a( a 是一个正整数)时刻进入,同时在 t1、t2、...、tm 时刻有 m 个客人进入。
编程求出自动门打开的次数,假定开始时门是关闭的。
【输入形式】
第一行4个正整数 n、m、a、d,分别表示员工数、客人数、第一个雇员进入的时刻、门打开后到关闭的时间长度。
第二行包括一个正整数序列 t1、t2、...、tm,表示 m 个客人来到门前的时刻,这是一个非递减序列。
【输出形式】
输出门打开的次数
【样例输入】
1 1 3 4 7
【样例输出】
1
//松雅旅馆的自动门
//松雅的旅馆门口有一个自动门,按照以下方式工作:
//
//当门是关闭的时候,1或多个人来到门前,门将马上自动打开,所有人都能马上入内;
//
//当门是打开的时候,1或多个人来到门前,所有人都能马上入内;
//
//打开的门在打开后的 d 秒钟内立即关闭;
//
//当门正在关闭时,1或多个人在同一时刻来到门前,所有人有足够时间入内,之后才会关闭
//
// 例如,如果 d=3,有4人在4个不同时刻t1=4、t2=7、t3=9 和 t4=13 来到门前,门将会打开3次,即在时刻4、9和13打开,在时刻7和12关闭。
//
// 已知有 n 个员工将在 a、2*a、3*a、...、n*a( a 是一个正整数)时刻进入,同时在 t1、t2、...、tm 时刻有 m 个客人进入。
//
// 编程求出自动门打开的次数,假定开始时门是关闭的。
#include<iostream>
using namespace std;
int main()
{
int n,m,a,d;
cin>>n>>m>>a>>d;
int *t=new int[n+m]; //将员工和客人时间合并到一起然后排序
for(int i=0;i<n+m;i++){
if(i<n){
t[i]=(i+1)*a;
}else{
cin>>t[i];
}
}
for(int i=0;i<n+m;i++){
for(int j=i+1;j<n+m;j++){
if(t[i]>t[j]){
int tem=t[i];
t[i]=t[j];
t[j]=tem;
}
}
}
int count=1; //一开始肯定会开门一次,如果有人的话
int close=t[0]+d; //关门时间
for(int i=0;i<n+m;i++){
if(t[i]>close){
count++; //大于关门时间,则要开门
close=t[i]+d; //关门时间更新
}
}
cout<<count<<endl;
return 0;
}