2024.3.24阶段性测试题解

VJ测试链接考试链接
成绩表如下,信息学是非常检验平时努力的,而且也是一分耕耘一分收获的,总的来说每天订正晚训跟只订正一部分题还是有区别的…希望同学们再接再厉。
在这里插入图片描述

A题
简单判断题,单独判断首字母,再判断其余字母。

#include<bits/stdc++.h>
using namespace std;
char s[500];
int main(){
	cin>>s+1;
	int n=strlen(s+1);
	bool ok=true;
	for(int i=2;i<=n;i++){
		if('a'<=s[i]&&s[i]<='z'){
			
		}
		else{
			ok=false;
			break;
		}
	}
	if(ok==true&&'A'<=s[1]&&s[1]<='Z')cout<<"Yes";
	else cout<<"No";
	return 0;
}

B题
首先你要知道,什么叫字母表顺序最早?
abcdefg....这就是字母表顺序
所以本题我们先统计每种字母的个数,从中找到数量最多的值
然后枚举字母表a~z,谁的数量=最大数量那么就是输出它

```cpp
#include<bits/stdc++.h>
using namespace std;
char s[1005];
int vis[30];
int main(){
	cin>>s+1;
	int n=strlen(s+1);
	int ma=0;
	for(int i=1;i<=n;i++){
		vis[s[i]-'a'+1]++;
		ma=max(ma,vis[s[i]-'a'+1]);
	} 
	for(int i=1;i<=26;i++){
		if(vis[i]==ma){
			cout<<char('a'+i-1);
			return 0;
		}
	}
	return 0;
}

C题
因为A菜需要N个菜各个材料才能做出来,最终能最多做出来多少个A菜取决于哪种材料是最经不起消耗的,也就是假如说某种材料能支持最多做800个A菜,但是另一种材料最多只支持做8个A菜,那么你只能最多做8个A菜,因为会涉及到材料不足的问题。所以我们先枚举一遍A菜的消耗,计算出i材料最多能支持做多少个A菜,取最小值,那么就能计算出最多能做出多少道A菜。

枚举制作i=0~i=A_max道A菜,然后枚举N个原材料的消耗,A的材料消耗了以后用剩余的材料去看看最多能计算多少个B菜,然后A的数量+B的数量就是总数,对总数取最大值就是我们最多能做的总菜数。注意存在消耗为0的情况。

#include<bits/stdc++.h>
using namespace std;
#define int long long  
int Q[20];
int A[20];
int B[20];
signed main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>Q[i];
	}
	int curA=1e7;
	for(int i=1;i<=n;i++){
		cin>>A[i];
		if(A[i]==0)continue;
		if(Q[i]/A[i]<curA){
			curA=Q[i]/A[i];
		}
	}//计算最多做多少个A   
	for(int i=1;i<=n;i++){
		cin>>B[i];
	}   
	int ans=0;bool ok=true;
	for(int i=0;i<=curA;i++){//制作I个A菜   
		int now=1e7;
		for(int j=1;j<=n;j++){
			if(Q[j]-i*A[j]<0){
				ok=false;
				break;
			}
			else if(Q[j]-i*A[j]==0){
				if(B[j]==0)continue;
				else now=0;
			}
			else if(B[j]!=0){
				now=min(now,(Q[j]-i*A[j])/B[j]);
			}
		} 
		if(!ok)break;
		ans=max(ans,i+now);
	}
	cout<<ans;
	return 0;
}

D题
简单题,枚举o即可

#include<bits/stdc++.h>
using namespace std;

signed main(){
	int n;
	cin>>n;
	cout<<"L";
	for(int i=1;i<=n;i++){
		cout<<"o";
	}
	cout<<"ng";
	return 0;
}




E题
求二进制末尾里面连续0的个数
。。。。其实就是类似于十进制数拆出每个数字位的方法
因为都是从低位开始拆的,也就是末尾
所以对数字N拆分二进制,不断除2 ,%2,余数为0说明当前这个位的数字是0,那么答案++,否则break

#include<bits/stdc++.h>
using namespace std;

signed main(){
	int n;
	cin>>n;
	int ans=0;
	while(n!=0){
		if(n%2==0)ans++;
		else break;
		n=n/2;
	}
	cout<<ans;
	return 0;
}




F题
这其实是进制思想的经典套路题
有所的位的取值情况只能是偶数,那么相当于你每一位上有5种情况,组合成数字,求第多少小的数字。

我们不妨想想这个问题,对于十进制数来说,每个位取值是0~9
我要求第x小的数如何求呢?
我们可以把x逐步地从低位开始摆放,因为十进制情况第x小就是数字x。同理把这个方法拓展到本题,每个位有五种选择,我们就当成5进制,那么问题就变成了把题目输入的N转换成5进制。5进制位上的0 实际上表示的是数字0 ,5进制位上的1,实际上表示的数字是2,5进制位上的2,实际上表示的是数字4…以此类推

最终就把数字求出来了
这个题实际上跟去年温州市赛的最后一题原理一模一样

#include<bits/stdc++.h>
using namespace std;
int A[500];
int B[10];
signed main(){
	long long int n;
	cin>>n;
	n--;
	if(n==0){
		cout<<0;return 0;
	}
	int len=0;
	B[0]=0;
	for(int i=1;i<=4;i++){
		B[i]=B[i-1]+2;
	}
	while(n!=0){
		A[++len]=B[n%5];
		n=n/5;
	}
	for(int i=len;i>=1;i--)
	cout<<A[i];
	return 0;
}




G题
我们考虑以ai结尾的最长左金字塔序列长度为L[i] ,以ai为首的最长右金字塔序列长度为R[i] ,那么实际上如果以ai作为金字塔中心,能够成的最长金字塔序列就是L[i] 跟R[i] 取最小值。

扫一遍所有的ai,就能求出答案。
问题是L[i]如何求解?
考虑一种状态转移
L[0]=0
那么对于ai来说,L[i]=min(L[i-1]+1,ai)
为什么呢? 因为左边以ai结尾,金字塔的最长长度绝对不可能比ai本身还要大; 如果能跟前面衔接一下,那么长度就是L[i-1]+1; 当然有同学好奇这样子转移,是如何做到"移除第一项或者最后一项 的" 我举个例子 1 1 1 1 2 3 4 5 从左到右依次对应的L[i]就是1 1 1 1 2 3 4 5,所以说如果存在a[i-1]与a[i]无法衔接的情况(因为衔接起来会导致当前L[i]>a[i]) ,但是上一步至多是持平的,所以说如此转移。

#include<bits/stdc++.h>
using namespace std;
int L[200005];
int R[200005];
int A[200005];
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>A[i];
	}
	for(int i=1;i<=n;i++){
		L[i]=min(L[i-1]+1,A[i]);
	}
	int ans=0;
	for(int i=n;i>=1;i--){
		R[i]=min(R[i+1]+1,A[i]);
		ans=max(ans,min(R[i],L[i]));
	}
	cout<<ans;
	return 0;
}
  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值