目录
1221.电梯
题目描述
在某一高层建筑内只有一部电梯,当你按下一个数时,电梯会运行到那一层。已知电梯每上升一层需6秒,下降一层需4秒,在需要停留的那层停留5秒。现有N个整数组成的一个需求列表,电梯将依次响应,电梯从0层开始运行,而在运行过程结束之前不会返回0层。
注意,若出现相邻两个整数相等,代表在同一层执行了两个不同任务,可以理解为:电梯已经停了5秒,正要关门时又有人在同一层按开门键,电梯又开门并停留5秒。
输入
输入分两行,第一行是一个正整数N(N<=1000),代表停留几次,第二行的N个数字代表这几次依次停留的楼层。
输出
输出电梯完成该任务序列所需的时间,单独占一行。
样例输入 Copy
3
2 3 1
样例输出 Copy
41
提示
电梯从0层上升到2层运行时间为12秒,停留5秒,再上升第三层,运行时间6秒,停留5秒,再下降到第一层,运行时间8秒,停留5秒。共41秒。
郑州轻工业大学oj上的一道基础题,使用while循环即可解决。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;//定义停留的次数,楼层数
int sum=0,i=0;//初始时间和楼层数
cin>>n;
while(n--){
cin>>m;
while(i<m){ //如果楼层数小于按下的楼层数,在上升
sum+=6;
i++;
}
while(i>m){
sum+=4;
i--;
}
if(i==m) sum+=5;//到了这一层,停留5秒
}
cout<<sum<<endl;
return 0;
}
1222.小球滚动问题
题目描述
有n个小球以每秒1cm的速度在一个滑槽上滑行,滑槽没有封口,所以当小球滑到滑槽的端点时将会掉落下来。滑槽的宽度只容许一个小球通过,小球之间的碰撞为弹性碰撞(即碰撞后小球速度的绝对值不变,方向相反)。
已知n个小球的初始位置,但不知道小球的朝向,小球与槽之间的摩擦力不计,请你计算所有小球掉下所需要的最短和最长时间(秒)。
输入:
第一行输入一个整数L表示滑槽的长度(单位:cm)(1<=L<=10^6);
第二行输入一个整数n代表小球的个数(1<=n<=10^6);
第三行输入n个整数,第i个整数Xi(1<=Xi<=L)代表第i个小球的初始位置(即,距离滑槽左端Xi厘米)
输出 :
输出一行两个整数,分别代表所有小球掉落的最短和最长时间(秒)
样例输入:
10
3
2 6 7
样例输出:
4 8
我们可以知道,当没有发生碰撞时,最后一个小球下洛的时间是所有小球下落的最短时间。
我们用q[]数组存每个小球的位置,由于不知道小球从哪边下落,对于每一个小球而言,如果没有发生弹性碰撞时,离最近的槽边滑出时,时间最短。
代码段如下:
for(int i=1;i<=n;i++)
cin>>q[i];//存每个小球的位置sort(q+1,q+n);//对小球的位置进行排序for(int i=1;i<=n;i++)
b[i]=min(q[i],L-q[i]);//存离哪个槽边最近的距离int maxi=b[1];
for(int i=2;i<=n;i++)
if(maxi<b[i]) maxi=b[i];//找到最后一个小球下落的时间,为所有小球下落最短时间
cout<<maxi<<" ";//优先输出最短时间

我们如何找最长时间呢?
同意的,我们可以找没有发生碰撞的最长时间,和发生碰撞的最长时间,最后比较哪一个大。
而没有发生碰撞的,又分为所有小球都往左方向滑动 ,所有小球都往右,我们找出两者的最大值。
由于所有小球离左端的距离在上面都是排好序的,则q[n]是离左端最大的距离,在所有小球往左滑动时,时间最大,同理,L-q[1] 是所有往右小球时间最大的一个,则此阶段的代码如下:
int max1=max(q[n],L-q[1]);//max1是所有没有发生碰撞时,所耗时间最大

而最后,就是最难理解的发生碰撞时的了,我们如何去讨论呢?
我们不妨假设第一个小球与第二个小球发生碰撞时,第三个小球往后所有的小球都向右移动,也就是说,除了第一个小球和最后一个小球,其他小球都是可以和左边或者右边的小球发生碰撞的。
我们不妨将此阶段又划分为两类:往右碰撞往左回,往左碰撞往右回 。
可能画出图比较好理解些:


编辑
这是往左碰撞往右弹,由于两者的速度相等,则i走的距离为l[i]=L-q[i]+q[i]-q[i-1],化简为l[i]=L-q[i-1],有点神奇哈,竟然可以消掉!
同理,往右碰撞往左回,r[i]=q[i]+q[i+1]-q[i],化简得r[i]=q[i+1]。
但是,我们刚刚护理了第一个和最后一个,我们添上:r[1]=q[2]-q[1],l[n]=L-q[n-1]。
接下来,我们上完整的代码:
#include<bits/stdc++.h>
#include<vector>
#include<string>
#include<algorithm>
#include<math.h>
using namespace std;
const int N=1e6+10;
int q[N],b[N],l[N],r[N];
int main()
{
int L,n;
cin>>L>>n;
for(int i=1;i<=n;i++) cin>>q[i];
sort(q+1,q+n);
for(int i=1;i<=n;i++){
b[i]=min(q[i],L-q[i]);
}
int maxi=b[1];
for(int i=2;i<=n;i++){
if(maxi<b[i]) maxi=b[i];
}
cout<<maxi<<" ";
int max1=max(q[n],L-q[1]);
for(int i=2;i<n;i++){
l[i]=L-q[i-1];
r[i]=q[i+1];
}
r[1]=q[2]-q[1];
l[n]=L-q[n-1];
int ma1=l[0];
for(int i=2;i<=n;i++)
if(l[i]>ma1) ma1=l[i];
int ma2=r[0];
for(int i=2;i<=n;i++)
if(r[i]>ma2) ma2=r[i];
cout<<max(max1,max(ma1,ma2));
return 0;
}

1205.你爱我吗?
题目描述
LCY买了个n束鲜花准备送给他暗恋的女生,但是他不知道这个女生是否喜欢他。这时候一个算命先生告诉他让他查花瓣数,第一个花瓣表示“爱”,第二个花瓣表示“不爱”,第三个花瓣表示“爱”......为了使最后的结果是爱,LCY需要从n束花中选出一些,你能帮他算出最后他送给女生的花中最多包含多少个花瓣吗?
输入
首先输入一个数T,表示测试的组数。
接下来T组测试实例,每组实例首先输入一行,包括一个整数n(1<=n<=100)。
然后输入一行,n个整数a1,a2,...,an(1<=ai<=100),表示每束花包含的花瓣的个数。
没有答案输出0
样例
输入
3
1
1
1
2
3
5 6 7
输出
1
0
13
我们发现只有最后是奇数时,才是“爱”, 而且如果是偶数的话,我们应该减去最小的奇数,因为偶数-奇数=奇数,如果所有花瓣中没有奇数,那么输出0.
代码如下:
#include<bits/stdc++.h>
using namespace std;
constint N=1e6+10;
int q[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int sum=0;
memset(q,0,sizeof(q));//初始化int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&q[i]);
sum+=q[i];
}
sort(q+1,q+n);//排序int y=0;
for(int i=1;i<=n;i++)
{
if(q[i]%2!=0)//找到第一小的奇数
{
y=q[i];break;
}
}
if(y==0&&sum%2==0) printf("0\n");//如果没有奇数并且sum和为偶数,则输出0else{
if(sum%2==0) sum-=y;
printf("%d\n",sum);
}
}
return 0;
}

1201.众数问题
问题描述
给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。
例如,S={1,2,2,2,3,5}。多重集S的众数是2,其重数是3.
对于给定的由n个自然数组成的多重集合S,计算S的众数和重数。
输入
第一行多重集S中元素的个数n(n<=50000);接下来的n行中,每行有一个自然数。
输出
输出文件有两行,第一行给出众数,第二行给出重数。(如果有多个众数,只输出较小的)。
样例输入
6
1
2
2
2
3
5
样例输出
2
3
一般的朴素做法
#include<bits/stdc++.h>
using namespace std;
constint N=1e6+10;
int q[N],vis[N];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&q[i]);
vis[q[i]]++;//记录这个数出现的次数
}
int max1=q[1];
for(int i=2;i<=n;i++)
if(max1<q[i]) max1=q[i];//找最大的下标int max2=1;
for(int i=1;i<=max1;i++)
{
if(vis[i]>vis[max2])
max2=i;
}
printf("%d\n%d",max2,vis[max2]);
return 0;
}

暴力做法
#include<bits/stdc++.h>
using namespace std;
constint N=1e6+10;
int max,t,ans,q[N],vis[N];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&q[i]);
for(int i=1;i<=n;i++)
{
ans=1;
for(int j=i+1;j<=n;j++)
if(q[i]==q[j]) ans++;
vis[i]=ans;
}
for(int i=1;i<=n;i++)
if(vis[i]>max)
{
max=vis[i];
t=q[i];
}
printf("%d\n%d",t,max);
return 0;
}

最后一种方法,我想到的就是排序加双指针,但一直AC不了,也不知道怎么回事。
我将思想说一下,比如1 2 3 2 2 经过排序之后1 2 2 2 3,然后我们用双指针。
for(int i=1;i<=n;i++)
{
int ans=1;
int j=i+1;

本文介绍了几个编程题目,包括电梯运行时间计算、小球滚动的最短和最长时间、众数问题、破解简单密码、统计立方数、等值数目、海选女主角等,涉及算法和逻辑推理,展示了如何使用C++解决这些问题。
最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



