一.比赛分数:
共四题,满分400,第一题30分,第二题30分,第三题10分,第四题10分,共得80分。
二.比赛过程:
第一题代码写的很长,就是用for循环if判断sort从大到小排序然后取第一个最大的数,数组开的挺大,还有双层for循环,时间超限,并且我感觉情况没有列完。
第二题没有判断向右移动 1 个格子这个条件,只把题目中样例的情况写上了,和x和y相同的情况。
第三题没大读明白题,在老师讲了后,就知道了,模拟赛时,是蹭的样例。
第四题没大读明白题,输入也是后来才弄明白的,模拟赛时,是蹭的样例。
三.题解报告:
(1)第一题:独木桥
情况:赛中30分,已补题
题意:独木桥上的人数 n,独木桥的长度 L , 第 i个人的初始位置到独木桥左端点的距离ai 米,计算出所有人同时出发,全部都离开独木桥所需的最短时间。
题解:可以取中间值,然后左右两边分别向对面走,判断时间最长的那个输出。
赛后总结:感觉这道题自己想得太复杂,并且在自己的代码里在测试的时候,桥是奇数时,输出的数就好像不大对,但相对来说很简单。
AC代码:
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<vector>
using namespace std;
int n,l,x;
int ans=0;
int main(){
cin>>n>>l;
for(int i=0;i<n;i++){
scanf("%d",&x);
ans=max(ans,min(x,(l-x)));
}
cout<<ans<<endl;
return 0;
}
(2)第二题:移动棋子
情况:赛中30分,已补题
题意:操作 1 :向右移动 1 个格子。
操作 2 :从当前棋子所在的 a 号格子,直接跳到 -a 号
计算把棋子从 x号格子移动到 y 号格子需要的最少操作次数。
题解:三个主要判断,第一个是x和y负数的,第二个是x和y正数的,第三个是x和y等于0的,里面是判断x和y谁大的。
赛后总结:我多判断了x和y都是0的情况。
AC代码:
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<vector>
using namespace std;
long long x,y,ans;
int main(){
cin>>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;
}
else if (x<y){
ans=y-x;
}
}
else {
ans=abs(x-y);
if (x>y){
ans=ans+1;
}
}
cout<<ans<<endl;
return 0;
}
(3)第三题:动物园
情况:赛中10分,已补题
题意:最少需要花费多少钱买门票才能看到所有种类的动物(同
一种动物可能不止看一个)。注意:只能买一张门票。
题解:利用了双指针的思想,l和r在一个下标上,假如动物种类数量是5,l和r往后移动,全部包含5种动物种类数后,是最优解后,场数*10,l和r再往后移, 再找到包含5种动物种类数,一直到r到n,输出最优解。
赛后总结:赛中没看懂,赛后老师讲后就懂了。
AC代码:
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<vector>
using namespace std;
int n,m,a[1000005],vis[1000005];
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int l=1,r=0,cnt=0,ans=0x3f3f3f3f;
while (r<n){
while (cnt<m&&r<n){
r++;
vis[a[r]]++;
if (vis[a[r]]==1){
cnt++;
}
}
while (cnt==m){
ans=min(ans,r-l+1);
vis[a[l]]--;
if (vis[l]==0){
cnt--;
}
l++;
}
}
printf("%d\n",ans*10);
return 0;
}
(4)第四题:摧毁
情况:赛中10分,已补题
题意:(1)使用定点激光武器花费 1 PW
的代价摧毁任意轨道上指定的一个卫星。
(2)使用脉冲轨道武器花费 c PW
的代价把某一轨道上的所有卫星摧毁。
求将这些卫星全部摧毁的最小代价是多少?
题解:用桶,如果定点激光武器花费的代价少,就用激光武器,如果脉冲轨道武器花费的代价少,就用脉冲轨道武器,最后输出激光武器花费的代价和脉冲轨道武器花费的代价。
赛后总结:赛中没看懂,赛后老师讲后就懂了。
AC代码:
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<vector>
using namespace std;
const int N=5e6+5;
int cnt[N],t;
int main(){
cin>>t;
while (t--){
int n,c,x,ans=0;
memset(cnt,0,sizeof cnt);
cin>>n>>c;
for (int i=1;i<=n;i++){
cin>>x;
cnt[x]++;
}
for(int i=1;i<=N;i++){
ans+=min(c,cnt[i]);
}
cout<<ans<<endl;
}
return 0;
}
四.赛事总结
本次比赛中写freopen的时候,想了后久才想的起来,以后要背熟,仔细检查文件,写题时也要多思考,不能马上下定论,觉得自己不会写。