CSP-x 题目讲解

第一题、逃离

时间限制:1秒        内存限制:256M

问题描述

小可逃离战争封锁地的过程中,邪恶军团又发射了导弹袭击!

好在小可身处群山之中,群山的山峰可以在一定程度上抵挡导弹的攻击。

小可提前知道了导弹的高度和山峰的侧视高度图,小可想知道导弹会命中哪座山峰。

如果导弹会袭击到小可输出danger

注意:从左到右第一个大于等于导弹高度的山峰会被命中。

输入格式

一行三个整数 N,M,K(1 \leq N,M,K \leq 100)N,M,K(1≤N,M,K≤100)。代表山峰的侧视高度,宽度和导弹的高度。

下面 NN 行是由空格和 * 号组成的长度为 MM 的字符串,代表山峰的具体形状,第 ii 列即为第 ii 座山峰。

输出格式

如果导弹能命中山峰,那么输出山峰的编号(最左边的山峰编号为 11),否则输出 danger

输入样例1
 
  1. 4 5 4
  2. *
  3. **
  4. ***
  5. *****
输出样例1
 
  1. 5
输入样例2
 
  1. 4 5 2
  2. *
  3. **
  4. ***
  5. *****
输出样例2
 
  1. 2
输入样例3
 
  1. 4 5 10
  2. *
  3. **
  4. ***
  5. *****
输出样例3
 
  1. danger
数据描述

本题无部分分数据。

从左到右能拦截哪一个山

来看看AC代码

#include<bits/stdc++.h>
using namespace std;
string s;
int b[105];
int main(){
	freopen("water.in","r",stdin);
	freopen("water.out","w",stdout);
	int n,m,k;
	cin>>n>>m>>k;
	getchar();
	for(int i=1;i<=n;i++){
		getline(cin,s);
		for(int j=0;j<s.size()-1;j++){
			if(s[j]=='*')b[j+1]++ ;
		}
	} 
	for(int i=1;i<=m;i++){
		if(b[i]>=k){
			cout<<i;
		}
	}
	cout<<"danger";
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int a[1000005],b[1000005];
int main(){
	//freopen("water.in","r",stdin);
	//freopen("water.out","w",stdout);
	int n,cnt=0;;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
	    scanf("%d%d",&a[i],b+i);
	}
	sort(a+1,a+1+n);
	sort(b+1,b+1+n);
	int i=1,j=1;
	while(i<=n){
	    if(a[i]>=b[j]){
	        j++,i++,cnt++;
	    }
	    else i++;
	}
	printf("%d",cnt);
	return 0;
}

第三题、删除挑战

时间限制:1秒        内存限制:256M

问题描述

删、删、删,用力的删除!

序列太长了, 小可阅读的时候就非常麻烦!

因此,小可要删除序列中一些数字!

具体地:有一个长度为 nn 的序列 aa,小可要删除其中 kk 个数字。

但是随机删除有点太难了,因此小可规定:每次只能删除数组中第一个位置元素,或者最后一个位置的元素。

当删除完 kk 个元素后,请你求一下最大的数组的和。

输入格式

第一行输入两个正整数 n,kn,k ,含义如题所示。

第二行输入 nn 个整数表示 aa 数组。

输出格式

输出一行包含一个整数,表示当删除完 kk 个元素后,请你求一下最大的数组的和。

输入样例1
  1. 5 4
  2. 8 13 7 8 6
输出样例1
  1. 13
数据描述

对于 30\%30% 的数据:1 \leq n \leq 101≤n≤10。

对于 100\%100% 的数据:1 \leq n \leq 5000,1 \leq k \leq n,1 \leq a_i \leq 10^91≤n≤5000,1≤k≤n,1≤a​i​​≤10​9​​。

题目转换成求连续k个数字的最大值

看看进阶AC代码

#include<bits/stdc++.h>
using namespace std;
int a[5005],n,k;
long long s[5005];
int main(){
	//freopen("water.in","r",stdin);
	//freopen("water.out","w",stdout);
	cin>>n>>k;
	for(int i=1;i<=n;i++){
	    cin>>a[i];
	    s[i]=s[i-1]+a[i];
	}
	k=n-k;
	long long ans=0,t;
	for(int i=k;i<=n;i++){
	    t=s[i]-s[i-k];
	    ans=max(ans,t);
	}
	cout<<ans;
	return 0;
}

第四题、手工课

时间限制:1秒        内存限制:256M

问题描述

达达老师是一位和蔼亲切的手工老师。

今天就由达达老师带领同学们在手工课制作一些好玩的东西吧。

在手工课开始前,达达老师就为同学们准备了 nn 根长度均为 uu 的手工材料。

班级里共有 kk 位同学,每位同学也同样准备了手工材料,已知,第 ii 同学准备的材料长度为 a_ia​i​​ 。

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

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

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

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

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

输入格式

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

第二行 kk 个整数,第 ii 个数表示 a_ia​i​​ 。

第三行 mm 个整数,第 ii 个数表示 b_ib​i​​ 。

输出格式

第一行,若能满足,输出 Yes ,否则输出 No 。

若第一行输出为 Yes ,则第二行输出一个整数,表示需要使用的最小的的材料长度之和。

输入样例1
 
  1. 3 10 6 7
  2. 1 1 4 5 1 4
  3. 1 9 1 9 8 1 0
输出样例1
 
  1. Yes
  2. 33
数据描述

对于 30\%30% 的数据,1 \leq n,k,m \leq 10,0 \leq u,a_i,b_i \leq 1001≤n,k,m≤10,0≤u,a​i​​,b​i​​≤100。

对于 100\%100% 的数据,1 \leq n,k,m \leq 10^5,0 \leq u,a_i,b_i \leq 10^91≤n,k,m≤10​5​​,0≤u,a​i​​,b​i​​≤10​9​​。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,u,m,k,a[2*N],b[N];
long long sum=0;
int main(){
	scanf("%d%d%d%d",&n,&u,&k,&m);
	for(int i=1;i<=k;i++) scanf("%d",a+i);
	for(int i=1;i<=m;i++) scanf("%d",b+i);
	for(int i=1;i<=n;i++) a[++k]=u;
	sort(a+1,a+1+k);
	sort(b+1,b+1+m);
	int i=1,j=1;
	while(b[j]==0&&j<=m) j++;
	while(i<=k&&j<=m){
	    if(b[j]<=a[i]){
	        sum += a[i];
	        j++,i++;
	    } else{
	        i++;
	    }
	}
	if(j<=m){
        cout<<"No";
	}
	else {
	    cout<<"Yes"<<endl<<sum;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值