自测160分
第一题 100分
第二题 20分
第三题 30分
第一题 20分
第一题 逃离
问题描述
小可逃离战争封锁地的过程中,邪恶军团又发射了导弹袭击!
好在小可身处群山之中,群山的山峰可以在一定程度上抵挡导弹的攻击。
小可提前知道了导弹的高度和山峰的侧视高度图,小可想知道导弹会命中哪座山峰。
如果导弹会袭击到小可输出danger。
注意:从左到右第一个大于等于导弹高度的山峰会被命中。
输入格式
一行三个整数 N,M,K(1≤N,M,K≤100)。代表山峰的侧视高度,宽度和导弹的高度。
下面 N 行是由空格和 * 号组成的长度为 M 的字符串,代表山峰的具体形状,第 i 列即为第 i 座山峰。
输出格式
如果导弹能命中山峰,那么输出山峰的编号(最左边的山峰编号为 1),否则输出 danger。
输入样例1
4 5 4
*
**
***
*****
输出样例1
5
输入样例2
4 5 2
*
**
***
*****
输出样例2
2
输入样例3
4 5 10
*
**
***
*****
输出样例3
danger
数据描述
本题无部分分数据。
解析
考试中想 因为有空格,所以要用getline(cin,a[i]);a[i]是字符串数组,然后用桶标记标记每个山的高度,然后从左往右数找第一个大于等于导弹高度的山,输出编号然后结束程序。如果没找到那么输出danger。
错思路 无
错代码 无
对思路 用桶标记
对代码
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
long long n,m,k,cnt[105];
string a[105];
int main() {
cin>>n>>m>>k;
for(int i=0;i<=n;i++){
getline(cin,a[i]);
}
for(int i=0;i<m;i++){
for(int j=0;j<=n;j++){
if(a[j][i]=='*') cnt[i+1]++;
}
}
bool f=0;
//for(int i=1;i<=m;i++){
//cout<<cnt[i]<<" ";
//}
//cout<<"\n";
for(int i=1;i<=m;i++){
if(cnt[i]>=k){
cout<<i;
f=1;
break;
}
}
if(!f){
cout<<"danger";
}
return 0;
}
第二题 晾腊肉
题目描述
小可奶奶晾晒出来的腊肉味道是一绝!
今年又到了晾晒腊肉的时候,奶奶早早开始准备。
小可的奶奶先拿出来了 n 个架子,然后每个架子的高度为 ai,架子用来晾晒腊肉。
已知,总共有 n 块腊肉,每块腊肉的大小为 bi。
腊肉会放在架子上,并且需要架子的高度 ai大于等于腊肉的大小bi 时,腊肉才不会触碰到地上。
小可主动的要帮助奶奶进行腊肉和架子之间的配对,使得更多的腊肉不会触碰到地上。
求最多能有多少腊肉不会触碰到地上。
输入描述
第 1 行有一个正整数 n,表示腊肉和架子数量。
接下来 nn 行,每行有两个整数 ai,bi ,含义如题所示。
输出描述
输出一个整数,表示最多能有多少腊肉不会触碰到地上。
输入样例
5
7 3
4 5
3 6
8 5
4 4
输出样例
4
样例解释
7配6,4配4,3无法使用,8配5,4配3,共四个。
数据范围
在 10% 数据下:n=2,1≤ai,bi≤100
另有 20% 数据:1≤10,1≤ai,bi≤100
另有 10% 数据: 1≤n≤106,1≤ai,bi≤106,所有的 ai 都相等。
对于全部数据:1≤n≤106,1≤ai,bi≤106
解析
考试中想 先输入再sort一下在用一个单层for循环比大小
错思路 单层for循环
错代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n,a[1000005],b[1000005],cnt;
int main() {
freopen("drying.in","r",stdin);
freopen("drying.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i];
}
sort(a+1,a+1+n);
sort(b+1,b+1+n);
for(int i=1;i<=n;i++){
if(a[i]>=b[i]) cnt++;
}
cout<<cnt;
fclose(stdin);
fclose(stdout);
return 0;
}
对思路 双指针
对代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n,a[1000005],b[1000005],cnt;
int main() {
freopen("drying.in","r",stdin);
freopen("drying.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i];
}
sort(a+1,a+1+n);
sort(b+1,b+1+n);
for(int i=1,j=1;i<=n;i++){
if(a[i]>=b[j]) cnt++,j++;
}
cout<<cnt;
fclose(stdin);
fclose(stdout);
return 0;
}
第三题 删除挑战
问题描述
删、删、删,用力的删除!
序列太长了, 小可阅读的时候就非常麻烦!
因此,小可要删除序列中一些数字!
具体地:有一个长度为 n 的序列a,小可要删除其中 k 个数字。
但是随机删除有点太难了,因此小可规定:每次只能删除数组中第一个位置元素,或者最后一个位置的元素。
当删除完 k 个元素后,请你求一下最大的数组的和。
输入格式
第一行输入两个正整数 n,k ,含义如题所示。
第二行输入 n 个整数表示 a 数组。
输出格式
输出一行包含一个整数,表示当删除完 kk个元素后,请你求一下最大的数组的和。
输入样例1
5 4
8 13 7 8 6
输出样例1
13
数据描述
对于 30%30% 的数据:1≤n≤10。
对于 100%100% 的数据:1≤n≤5000,1≤k≤n,1≤ai≤109。
解析
考试中想 用双指针一个前一个后 如果前小于后删前 否则删后
错思路 双指针
错代码
#include<iostream>
#include<cstdio>
using namespace std;
long long n,k,a[50005],sum;
int main() {
freopen("del.in","r",stdin);
freopen("del.out","w",stdout);
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
long long l=1,r=n;
while(k--){
if(a[l]>a[r]) r--;
else l++;
}
for(int i=l;i<=r;i++) sum+=a[i];
cout<<sum;
fclose(stdin);
fclose(stdout);
return 0;
}
对思路 前缀和
对代码
#include <iostream>
using namespace std;
long long pre[5005];
int main() {
int n, k;
cin >> n >> k;
k = n - k;
long long res = 0;
for (int i = 1; i <= n; ++i) {
cin >> pre[i];
pre[i] += pre[i - 1];
if (i >= k)
res = max(res, pre[i] - pre[i - k]);
}
cout << res << endl;
return 0;
}
第四题 手工课
问题描述
达达老师是一位和蔼亲切的手工老师。
今天就由达达老师带领同学们在手工课制作一些好玩的东西吧。
在手工课开始前,达达老师就为同学们准备了 n 根长度均为 u 的手工材料。
班级里共有 kk 位同学,每位同学也同样准备了手工材料,已知,第 i 同学准备的材料长度为 ai 。
手工作品最终完成后,要送给 m 位受人尊敬的老师,每位老师需要的手工作品高度需要是 bibi。
注意:为了方便,假设手工材料可以制作出等高度的手工作品。
为了满足老师们对手工作品高度的要求,达达老师会与学生把某些材料切成两段,并留下需要的那一段,此时另一段成为边角料,不可以再继续使用。
现在,达达老师想要知道现有的手工材料能否满足所有的要求,若是满足,请输出需要使用的最小的的材料长度之和。
注意:如果一个材料被切成了两段,成为边角料的那一段也属于需要使用的材料。
输入格式
第一行四个整数 n,u,k,m。
第二行 k 个整数,第 i 个数表示 ai 。
第三行 m 个整数,第 i 个数表示 bi 。
输出格式
第一行,若能满足,输出 Yes ,否则输出 No 。
若第一行输出为 Yes ,则第二行输出一个整数,表示需要使用的最小的的材料长度之和。
输入样例1
3 10 6 7
1 1 4 5 1 4
1 9 1 9 8 1 0
输出样例1
Yes
33
数据描述
对于 30%30% 的数据,1≤n,k,m≤10,0≤u,ai,bi≤1001≤n,k,m≤10,0≤u,ai,bi≤100。
对于 100%100% 的数据,1≤n,k,m≤105,0≤u,ai,bi≤1091≤n,k,m≤105,0≤u,ai,bi≤109。
解析
考试中想 骗分
错思路 无
错代码 无
对思路 完整做法就是:分别对两个序列进行排序,然后从前往后遍历 ,如果当前的 满足要求,就记录答案,然后继续往后找。
对代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m, k;
int u, a[N << 1], b[N];
long long ans;
signed main() {
scanf("%d %d %d %d", &n, &u, &k, &m);
n += k;
for (int i = 1; i <= n; ++i)if (i <= k)
scanf("%d", &a[i]);
else
a[i] = u;
for (int i = 1; i <= m; ++i)
scanf("%d", &b[i]);
sort(a + 1, a + n + 1);
sort(b + 1, b + m + 1);
int aid = 1, bid = 1;
while (b[bid] == 0)
++bid;
while (aid <= n) {
if (bid > m)
break;
if (a[aid] >= b[bid])
++bid, ans += a[aid];
++aid;
}
if (bid <= m)
puts("No");
else
printf("Yes\n%lld\n", ans);
return 0;
}
2113

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



