coduck模拟四 侯锦呈 补题报告

自测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 个架子,然后每个架子的高度为 a​i​​,架子用来晾晒腊肉。

已知,总共有 n 块腊肉,每块腊肉的大小为 b​i​​。

腊肉会放在架子上,并且需要架子的高度 a​i​​大于等于腊肉的大小b​i​​ 时,腊肉才不会触碰到地上。

小可主动的要帮助奶奶进行腊肉和架子之间的配对,使得更多的腊肉不会触碰到地上。

求最多能有多少腊肉不会触碰到地上。

输入描述

第 1 行有一个正整数 n,表示腊肉和架子数量。
接下来 nn 行,每行有两个整数 a​i​​,b​i​​ ,含义如题所示。

输出描述

输出一个整数,表示最多能有多少腊肉不会触碰到地上。

输入样例

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,所有的 a​i​​ 都相等。

对于全部数据: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 同学准备的材料长度为 a​i​​ 。

手工作品最终完成后,要送给 m 位受人尊敬的老师,每位老师需要的手工作品高度需要是 bib​i​​。

注意:为了方便,假设手工材料可以制作出等高度的手工作品。

为了满足老师们对手工作品高度的要求,达达老师会与学生把某些材料切成两段,并留下需要的那一段,此时另一段成为边角料,不可以再继续使用。

现在,达达老师想要知道现有的手工材料能否满足所有的要求,若是满足,请输出需要使用的最小的的材料长度之和。

注意:如果一个材料被切成了两段,成为边角料的那一段也属于需要使用的材料。

输入格式

第一行四个整数 n,u,k,m。

第二行 k 个整数,第 i 个数表示 a​i​​ 。

第三行 m 个整数,第 i 个数表示 b​i​​ 。

输出格式

第一行,若能满足,输出 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,a​i​​,b​i​​≤100。

对于 100%100% 的数据,1≤n,k,m≤105,0≤u,ai,bi≤1091≤n,k,m≤10​5​​,0≤u,a​i​​,b​i​​≤10​9​​。

解析 

考试中想 骗分

错思路 无

错代码 无

对思路 完整做法就是:分别对两个序列进行排序,然后从前往后遍历 ,如果当前的 满足要求,就记录答案,然后继续往后找。

对代码

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值