一、做题情况
第一题比赛 000/100
第二题比赛 060/100
第三题比赛 000/100
第四题比赛 100/100
总分:160分
二、题解报告
T1、
独木桥(bridge)
题目描述
长度为 𝐿米的独木桥上有 𝑛个人,他们每个人都想以最快的时间离开危险的独木桥。已知每个人在独木桥上的行走速度为 1 米 / 秒 ,每个人只要能走到独木桥的两个端点中的其中一个就可以离开独木桥。
由于独木桥的桥面宽度很窄,只能容纳一个人通过,当两个人相遇时,他们无法交错通过,只能各自调转方向,继续沿反方向行走。
给你独木桥上的人数 𝑛,独木桥的长度 𝐿, 第 𝑖 个人的初始位置到独木桥左端点的距离𝑎𝑖米(每个人开始的朝向未知,但他们可以根据需要随时调转行走的方向)。
请计算出所有人同时出发,全部都离开独木桥所需的最短时间。
输入格式(输入文件为 bridge.in)
第一行一个整数 𝑛,表示人数。
第二行一个整数 𝐿,表示独木桥的长度(米)。
第三行是𝑎1,𝑎2…𝑎𝑛,其中 𝑎𝑖表示第 𝑖个人初始位置到独木桥左端点 的距离。
输出格式(输出文件为 bridge.out)
输出一行一个整数,表示所有人都离开独木桥所需的最短时间。
输入样例 #1
3
10
2 6 7
输出样例 #1
4
输入样例 #2
7
214
11 12 7 13 176 23 191
输出样例 #2
38
数据范围
对于 50% 的数据:
1≤𝑛≤10^3
对于 100% 的数据:
1≤𝑛≤10^6,1≤𝐿≤10^6,0≤𝑎𝑖≤𝐿
错因:我的思路是将所有的位置排了序,然后输出中间值,但这个思路有两个缺点:1.中间点不一定有人。2.他向右走可能比向左走短。如下图:
R:人
1. _R_R_ 2._R__
^
|
中间点
样例解析:2里右左最近,用2秒,6和7离右近,向左走,用10-6=4秒,4>2,所以一共用四秒。
题目解析:每个人过桥的距离最小为min(ai,L-ai),然后再从中去取最大的。
正解:
#include<iostream>
using namespace std;
int l,n,ans,a,minn;
int main(){
scanf("%d %d",&n,&l);
for (int i=1;i<=n;i++){
scanf("%d",&a);
minn=min(a,l-a);//求们个人过桥的最短时间
ans=max(ans,minn);//求出所有是过桥时间的最大值
}
printf("%d",ans);
return 0;
}
T2:
移动棋子(chess)
题目描述我的提交题解
时间限制:1秒 内存限制:128M
题目描述
一维的棋盘上有无限多个格子,每个格子都有一个编号,最中间的格子编号为0,0 号格子向右依次编号为 1,2,3,… ,向左依次编号为 −1,−2, ,−3,… 。
小明的目标是要将一枚棋子从
𝑥号格子移动到
𝑦号格子。
每一次操作有两种选择:
操作 1 :向右移动 1 个格子。
操作 2:从当前棋子所在的 𝑎号格子,直接跳到 −a 号格子(如:可以从 6 直接跳到 −6 ,也可以从 −6 直接跳到 6 )。
可以证明,无论整数
𝑥和
𝑦的值是多少,目标总是可以实现的。
请你设计程序,帮小明计算把棋子从
𝑥号格子移动到 𝑦 号格子需要的最少操作次数。
输入格式(输入文件为 chess.in)
一行,两个整数
𝑥和
𝑦, 表示要将棋子从
𝑥 号格子移动到
𝑦号格子。
输出格式(输出文件为 chess.out)
一个整数,表示小明把棋子从
𝑥号格子移动到
𝑦号格子需要的最少操作次数。
输入样例 #1
10 20
输出样例 #1
10
输入样例 #2
10 -10
输出样例 #2
1
输入样例 #3
-10 -20
输出样例 #3
12
数据范围
对于 30% 的数据:|x|≤100,|y|≤100 ;
对于 100% 的数据:
𝑥,𝑦都为整数;|x| ≤ 10^9,|y|≤10^9;
𝑥,𝑦不相等。
有 40% 的数据,|x|>|y|。
有 40% 的数据,|x|<|y|。
有 20% 的数据,|x|=|y|。
错因:这道题我用If - else if - else 语句将所有可能写出来判断,得了60分,我列了 x<y和y>x两种情况,但正解有x.y同号,x.y不同号,。x.y同号有x<y和y<x两种,x.y不同号也有x<y和y<x两种,x.y有一个为0有x为0和y为0两种情况。
样例解释:#3要先取反,-10变成10。10再加10次1,变成20,20再取反,变成-20,一用12次操作。
题目解析:这道题可以用if-else if语句来枚举每一种情况。
正解:
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
long long x,y,ans;
int main(){
scanf("%lld %lld",&x,&y);
if (x*y<0) ans=abs(abs(x)-abs(y))+1;
else if (x*y>0){
if (x>y) ans=x-y+2;
if (x<y) ans=y-x;
}
else{
ans=abs(x-y);
if (x>y)ans++;
}
printf("%lld",ans);
return 0;
}
T3:
学习中
动物园
题目描述我的提交题解
时间限制:1秒 内存限制:128M
题目描述
某动物园里有n个场馆和m种动物(m≤n)。n个场馆的编号分别用 1,2,3,..,n 表示;m种动物的编号分别用 1,2,3,..,m 表示。每一个场馆中只饲养了一只动物,不同的场馆可能饲养着相同种类的动物。
这个动物园的门票比较特殊,游客在购买门票时必须说明要参观的场馆的起止编号a和b(起止编号会打印到游客购买的门票上),代表游客只能参观动物园的第a个场馆至第b个场馆(包含 a,b)里的动物,其他的场馆不能去。门票按一个场馆十元收费。
如果你购买的门票的起止场馆编号是 3 到 8,那么你需要花 60 元钱购买门票,只能观看3,4,5,6,7,8 号场馆的动物。
小明希望看到动物园内所有种类的动物,同时小明是个非常节约的孩子,他希望花最少
的钱买门票。 请你帮小明计算:他最少需要花费多少钱买门票才能看到所有种类的动物(同
一种动物他可能不止看一个)。注意:小明只能买一张门票。
输入格式(输入文件为 zoo.in)
第一行两个整数 n,m,分别表示动物园内的场馆数量及动物种类数量。
第二行是
𝑥1,𝑥2,⋯,𝑥𝑛其中xi表示第i个场馆中的动物种类编号。
输出格式(输出文件为 zoo.out)
一行一个整数p,表示小明的门票费用。
输入输出样例
样例 1 输入
12 5
2 5 3 1 3 2 4 1 1 5 4 3
样例 1 输出
60
数据范围
对于 30% 的数据,有n≤200,m≤20。
对于 60% 的数据,有n≤1000,m≤1000。
对于 100% 的数据,有1≤n≤10^6,1≤xi≤m≤2×10^3
错因:二分的方法用错
我的: 正解:
l--> <--r l,r-->
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
———————————————————————————————— ————————————————————————————————
样例解释:从第二个开始,到第八个,一共60元。
题目解析:这道题r向后,直到有m个不同的动物,l++,缩小范围重复直到r==n。
正解:
#include<iostream>
using namespace std;
long long n,m,vis[1000001],a[1000001],minn=100000001,cnt;
int main(){
scanf("%lld %lld",&n,&m);
for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
long long L=1,R=0;
while(R<n){
while(cnt<m&&R<n){
R++;
vis[a[R]]++;
if (vis[a[R]]==1) cnt++;
}
while(cnt==m){
minn=min(minn,R-L+1);
vis[a[L]]--;
if (vis[a[L]]==0) cnt--;
L++;
}
}
printf("%lld",minn*10);
return 0;
}
T4:
摧毁
题目描述我的提交题解
时间限制:1秒 内存限制:128M
题目描述
坐地日行八万里,巡天遥看一千河。2077年,人类不仅仅是赛博科技得到了发展,太空技术也已经得到了极大的发展。地球的不同外轨道上已经充斥着各种功能用途的人造卫星。因为一个轨道上的卫星数量是有上限的,且卫星更新换代速度很快,如果想要发射新的卫星,需要把所有旧的卫星摧毁。
人类有两种不同的武器可以摧毁卫星,具体如下(其中PW为新的能量单位):
(1)使用定点激光武器花费 1 PW 的代价摧毁任意轨道上指定的一个卫星。
(2)使用脉冲轨道武器花费 c PW 的代价把某一轨道上的所有卫星摧毁。
现在有n个旧卫星分布在不同的外轨道上,你的任务是摧毁这些旧卫星。给出这n个卫
星的轨道编号,求将这些卫星全部摧毁的最小代价是多少?
输入格式( 输入文件名为 destroy.in)
第一行一个正整数T,表示测试数据组数。
接下来对于每组测试数据(注意:每组测试数据有2行数据,以下共2∗T行数据):
第一行两个正整数和c表示需要摧毁的卫星数量和使用脉冲轨道武器的代价。
第二行 是
𝑥1,𝑥2,⋯,𝑥𝑛,其中𝑥𝑖表示第i个卫星的轨道编号。
输出格式( 输出文件名为 destroy.out)
输出T行答案,对于每组测试数据,输出一行一个整数表示摧毁所有卫星的代价。
输入输出样例
样例 1 输入
4
10 1
2 1 4 5 2 4 5 5 1 2
5 2
3 2 1 2 2
2 2
1 1
2 2
1 2
样例 1 输出
4
4
2
2
数据范围
对于 30% 的数据,T=1,1≤n≤10,1≤ai≤10,1≤c≤10;
对于 60% 的数据,1≤n≤10^3 ,1≤a
i
≤1000,1≤c≤100;
对于 100% 的数据,1≤T≤10,1≤n≤10^6,1≤ai≤10^6
,1≤c≤100, 且所有测试数据的加起来不超过10^6
错因:无
题目解析:这道题我用了桶标记,如果个数比轨道武器的能量要低,就用轨道武器,否则就用激光武器。
正解:
#include<cstdio>
#include<cstring>
using namespace std;
long long cnt[1000001],t,n,c,sum,a;
int main(){
scanf("%lld",&t);
while(t--){
sum=0;
memset(cnt,0,sizeof(cnt));
scanf("%d %d",&n,&c);
for (int i=1;i<=n;i++){
scanf("%d",&a);
cnt[a]++;
}
for (int i=1;i<=n;i++){
if (cnt[i]>=c) sum+=c;
else sum+=cnt[i];
}
printf("%lld\n",sum);
}
return 0;
}