得分100
题目解析
第一题
题目描述:
牛牛在注册不同的网站时,总是会使用不同的密码来保证他的账号安全。
为了保证他的密码强度,牛牛使用他的“字符串筛选器”来测试密码的强度。
具体来说,他先将输入的字符串筛选分成四部分。
第一部分仅由小写英文字母组成
第二部分仅由大写英文字母组成
第三部分仅由0到9的数字组成
第四部分由其余特殊字符组成
这四部分要保留它们在原字符串中的相对顺序。
比如将"1q2w3E4R5{6}"这个字符串进行筛选后
四部分分别为:"qw"、"ER"、"123456"、"{}"。
然后只要某一部分不为空,牛牛就认为他的密码等级高1级。
密码等级最低为1级,最高4级。
例如"asdA@123"的密码等级为4,"20020101"的密码等级为1。
请帮助牛牛判断他注册账号时的密码等级,以及该密码做字符串筛选后的结果。
解题思路:考察语言,直接模拟即可。
代码:
#include<bits/stdc++.h>
using namespace std;
string x[4], s;
int ans;
int main(){
cin >> s;
int len = s.length();
for(int i = 0; i < len; i ++){
if(s[i] <= 'z' && s[i] >= 'a'){
x[0] += s[i];
continue;
}
if(s[i] <= 'Z' && s[i] >= 'A'){
x[1] += s[i];
continue;
}
if(s[i] <= '9' && s[i] >= '0'){
x[2] += s[i];
continue;
}
x[3] += s[i];
}
for(int i = 0 ; i < 4; i ++){
if(x[i].size()) ans ++;
else x[i] = "(Null)";
}
printf("password level:%d
", ans);
for(int i = 0 ; i < 4; i ++){
cout << x[i] << endl;
}
return 0;
}
第二题
题目链接
解题思路:
这道题是个贪心,考试的时候想用搜索来做(枚举每个点,然后向前和向后搜),结果写挂了。
看了题解,发现往回走是一个迷惑选项,只要一直往前(往右,即1 --> n + 1的方向)走就行了
在向右走的过程中更新一个能走到的最远的点的编号,和最近的能到达最远的点的编号(因为要维护字典序),如果当前走到的点就是最远能到达的点,说明不论怎样走都无法在往前,就是用魔法,使用魔法的点的编号就是最近的能到达最远的点的编号。如果最远能到达的点大于n,说明可以走到,结束输出就可以了。
这块有点绕,看代码就清楚了。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,num,minpos=1,maxdis=1,a[N],ans[N];
/*
num表示施展法术的数目;
minpos表示(两段施展法术之间区间的位置中)离最远能达到点最远的位置,即上述i位置;
maxdis表示(施展下一次法术之前)能达到的最远距离,即上述绿色位置;
ans[i]表示第i次施展法术的位置。
*/
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
if(a[i]){
if(i+a[i]>maxdis){//如果能跳到的最远距离比记录的maxdis大
maxdis=i+a[i];//刷新
minpos=i;//记录下来能跳到最远距离对应的第一个位置,就是最靠左的位置
}
}
else if(maxdis==i){//前面区间的位置最远也就到i(此i非上述i,而是循环遍历到的i)了,必须施展法术了
ans[++num]=minpos;//把记录的最靠前的能一次到达最远距离的位置,加入答案中
maxdis=i+1;//更新最远能到达的位置为i+1
minpos=i+1;//更新最靠前能到达maxdis的位置为i+1
//上面两步可以理解为“又回到最初的起点,记忆中你青涩的脸……”,就相当于又开辟了一段区间,而这段区间的左端点正是你上次施展法术后刚好到达的位置。略讲在另附中。
}
if(maxdis>n) break;
}
cout<<num<<endl;
for(int i=1;i<=num;i++) cout<<ans[i]<<' ';
}
这个是题解的代码。
题解写的比我写的清楚:链接
第三题
目测是个并查集,考试的时候一直在写第二题,没来得及看。
正在研究,持续更新......