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