概述:
介于有学弟问我题目,并且有些疑问自己在CSDN搜索也不知如何搜索出想要的东西(当然其实都是从初学者过来的,在我自己摸索时,也有遇到过类似情况)。故有此想法,写此题解,与其说是题解,倒不如说给大家分享一些博客与代码,在补题时(正所谓,比赛不补题,等于没比),可以轻松点,第一次用CSDN写东西,不太熟练,或许有些小问题,请多担待。
#第一题
printf语法题,按题目要求输出即可。
#第二题
经典oj第一题a+b,多了个未知测试数据数量来进行读入,虽然是竞赛基本tips,但对于大多数同学来说,可能会不太友好,不过见过一次,学一下,基本也就会了。
多组测试数据介绍 详情见博客添加链接描述
提供给新生C语言的写法
//写法一
#include<stdio.h>
int main(){
int a,b;
while(~scanf("%d %d",&a,&b)){
printf("%d\n",a+b);
}
return 0;
}
//写法二
#include<stdio.h>
int main(){
int a,b;
while(scanf("%d %d",&a,&b)!=EOF){
printf("%d\n",a+b);
}
return 0;
}
C++写法
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b;
while(cin>>a>>b){
cout<<a+b<<endl;
}
return 0;
}
#第三题
字符串模拟题,新生可能没学到字符串,或许一些同学对于字符串理解较少,但其实实现并不难,主要还是卡在多组测试数据数量,读入无法处理
题解:如何循环遍历整个字符串有多种方式,可以选择自己习惯的方式。一方面就是判断字符串是否超过8个字符,另一方面就是是否满足题目要求;就是四类字符出现三类,在遍历的时候加以if else进行判断,如果出现的话,它那一类的贡献就是1,最后四种数加起来的贡献超过3,即为合法字符串;
值得一提的是这里判断字母,数字,可以用到这几个函数来简化操作:
int islower(int c):检查字符是否为小写的字母;(a~z)
int isupper(int c):检查字符是否为大写字母;(A~Z)
int isdigit(int c):检查字符是否为十进制数字;(0~9)
想尝试的同学,可以自己试试呢,不要忘了头文件啊,不过这道题体现不出优势,一些题目用类似这些函数,可以简化代码,减少错误。
这是博客链接,介绍了一些字符串函数添加链接描述
C语言代码
#include<stdio.h>
#include<string.h>
int check(char s[]){ //判断字符串是否合法,合法返回true,不合法返回false
int n=strlen(s),i;
if(n<8) return 0; //长度小于8,不符合题意,返回false;
int a=0,b=0,c=0,d=0; //每一类默认是0,出现的这一类的,他的贡献即为1;
for(i=0;i<n;i++){
if(s[i]>='0'&&s[i]<='9') a=1;
if(s[i]>='a'&&s[i]<='z') b=1;
if(s[i]>='A'&&s[i]<='A') c=1;
if(s[i]=='~'||s[i]=='!'||s[i]=='@'||s[i]=='#'||s[i]=='$'||s[i]=='%'||s[i]=='^') d=1;
}
return (a+b+c+d)>=3;
}
int main(){
char s[20];
while(~scanf("%s",s)){
if(check(s)==1) puts("YES");
else puts("NO");
}
return 0;
}
C++代码
#include<bits/stdc++.h>
using namespace std;
bool check(string s){ //判断字符串是否合法,合法返回true,不合法返回false
int n=s.size();
if(n<8) return false; //长度小于8,不符合题意,返回false;
int a=0,b=0,c=0,d=0; //每一类默认是0,出现的这一类的,他的贡献即为1;
for(int i=0;i<n;i++){
if(s[i]>='0'&&s[i]<='9') a=1;
if(s[i]>='a'&&s[i]<='z') b=1;
if(s[i]>='A'&&s[i]<='Z') c=1;
if(s[i]=='~'||s[i]=='!'||s[i]=='@'||s[i]=='#'||s[i]=='$'||s[i]=='%'||s[i]=='^') d=1;
}
return (a+b+c+d)>=3;
}
int main(){
string s;
while(cin>>s){
if(check(s)==true) puts("YES");
else puts("NO");
}
return 0;
}
#第四题
题目有这么一点锅,鉴于习惯,N的大小未知,导致一看就不想写,不过一看就是一个贪心题,并且在网上搜索后,发现是蓝桥某一年省赛的题,并且N最大只有10左右,而且是保证数据按照原点的顺序递增的,这些在题目中表达的都不是很明确,不是很友好。(新生可以先放放这一题,别的模拟题可以补一补,写一写)
网上有现成的题解与代码,也就直接把博客分享给各位了添加链接描述
#第五题
经典01背包问题:属于动态规划入门题。题目转换一下,就是求在体积为m的情况下,把所有物品能凑成小于m的最大体积(即经典01背包问题),m减去这个最大体积,就是要求的答案。(新生可以先放放这一题,别的模拟题可以补一补,写一写)
给一个01背包博客,感兴趣的同学可以自己看看添加链接描述
仅提供一个C++的代码,
#include<bits/stdc++.h>
using namespace std;
int f[200010]; //全局变量,初始值自然为0;
int main(){
int m,n,maxs=0;
cin>>m>>n;
f[0]=1; //初始体积可以为0,初始化
for(int i=1,v;i<=n;i++){ //枚举物品
cin>>v;
for(int j=m;j>=v;j--){ //枚举体积
f[j]|=f[j-v];
if(f[j]==1) maxs=max(maxs,j);
}
}
cout<<m-maxs<<endl;
return 0;
}
#第六题
依旧是经典字符串模拟题,不过可以是我阅读理解比较差,那个输出看了几遍都没太看懂,后来似乎试懂了,但是也老是有问题,然后因为校赛,比较随意,WA的比较多,也懒得写第四题了(反正没法AK),还有点事,就先走了。后续发现了问题所在,当n=1的时候,是there is,n不为1是,应该是there are。
解析:遍历字符串,对每个字符进行判断,然后同时进行修改,这里需要注意就是他的输出条件,不妨开一个char数组来存放答案,按要求即可。
C语言:(感谢孟帅同学提供的代码,我就不用写了)
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int n;
scanf("%d", &n);
int m = 0;
int N = n;
char na[1010][100];
char pss[1010][100];
memset(na, 0, sizeof(na));
memset(pss, 0, sizeof(pss));
while (N--) {
char name[15],ps[15];
scanf("%s %s", name, ps);
int isc = 0; //标记数字是否被修改过
int i = 0;
while (ps[i] != '\0') { //判断字符串是否到结尾了
if (ps[i] == '1') {
ps[i] = '@';
isc = 1;
}
if (ps[i] == '0') {
ps[i] = '%';
isc = 1;
}
if (ps[i] == 'l') {
ps[i] = 'L';
isc = 1;
}
if (ps[i] == 'O') {
ps[i] = 'o';
isc = 1;
}
i++;
}
if (isc == 1) { //若密码被修改了,进行相应处理
memcpy(na[m], name, sizeof(name)); //在同一个下标下,一个数组存的名字
memcpy(pss[m], ps, sizeof(ps)); //在同一个下标下,另一个数组存的密码
m++; //该数字下存完,下一个加一
}
}
if (0 == m) {
if (1 == n) printf("There is 1 account and no account is modified\n");//有个坑点,如果总数是一个人要用is
else printf("There are %d accounts and no account is modified", n);//多个人,这里是are
}
else {
printf("%d\n", m); //打印修改的人数,并遍历输出
for (int i = 0; i < m; i++) {
printf("%s %s\n", na[i], pss[i]);
}
}
return 0;
}
C++:
#include<bits/stdc++.h>
using namespace std;
pair<string,string> q[1010];
bool check(string &s){ //注意这里的引用,对s字符串进行了修改
bool flag=false; //字符串flag标记,flag为flase是未被修改
for(int i=0;i<s.size();i++){
if(s[i]=='1'){
s[i]='@';
flag=true;
}else if(s[i]=='0'){
s[i]='%';
flag=true;
}else if(s[i]=='l'){
s[i]='L';
flag=true;
}else if(s[i]=='O'){
s[i]='o';
flag=true;
}
}
return flag; //若字符串被修改了,返回true;
}
int main(){
int n;
cin>>n;
int cnt=0;
string s1,s2;
for(int i=1;i<=n;i++){
cin>>s1>>s2;
if(check(s2)){ //check判断的同时修改
q[++cnt]={s1,s2}; //若该字符串被秀了,自加一个位置添加数据;
}
}
if(cnt==0){
if(n==1){ //有个坑点,如果总数是一个人要用is
printf("There is 1 account and no account is modified\n");
}else{ //多个人,这里是are
printf("There are %d accounts and no account is modified", n);
}
}else{
printf("%d\n",cnt);
for(int i=1;i<=cnt;i++) //循环遍历输出cnt修改后的人的信息
cout<<q[i].first<<' '<<q[i].second<<endl;
}
return 0;
}
#第七题:
题解:题目意思很明确,就套娃,按着他的要求执行即可,需要写一个change()函数和一个check()函数;
check()函数:判断字符串是否回文,鉴于自己介绍不清楚,在此给大家分享一个博客,感兴趣可自行查看
添加链接描述
change()函数:进制模拟,一个数,加上他的倒序数,即把原数字翻转,然后从低位往高位相加,注意最后有可能最高位有进位,记得处理一下最后的一位(并且会且只会多一会,可以用十进制试一下,比如987+789,是不可能变成5位数的)
鉴于拿C语言实现比较麻烦(好吧,我比较懒,不想再写一遍了),个人只提供一种C++的写法:
#include<bits/stdc++.h>
using namespace std;
bool check(string s){ //判断字符串是否回文,方法多种多样,可选择自己习惯的方式
int i=0,j=s.size()-1;
while(i<j){
if(s[i]==s[j]){
i++,j--;
}else{
return false;
}
}
return true;
}
string change(string s1,int n){
string s2=s1; //拷贝原字符串
reverse(s2.begin(),s2.end()); //原串s1的翻转字符串
string res; //存放结果字符串
int ans=0; //用来模拟进位
for(int i=s1.size()-1;i>=0;i--){ //循环从后往前,从个位开始累加
int a,b; //a存的是原字符串在第i的数字的大小,b存的是翻转后的s在第i的数字
if(s1[i]>='0'&&s1[i]<='9') a=s1[i]-'0'; //s[i]是数字,那他的大小就是它和'0'之间的差值
else a=s1[i]-'A'+10; //s[i]是字母,他的大小是它和'A'之间的差值在加10,因为A对应的是10
if(s2[i]>='0'&&s2[i]<='9') b=s2[i]-'0'; //处理逆序
else b=s2[i]-'A'+10;
ans+=a+b; //累加
int temp=ans%n; //求出当前的值
ans/=n; //保留进位
if(temp<=9) res+=temp+'0';
else res+=temp-10+'A';
}
//处理最后一位是否非0,非0则需要填加一位
if(ans>0&&ans<=9) res+=ans+'0';
else if(ans>=10) res+=ans-10+'A';
//得到的是逆序的数字,此时需要翻转,才能得到原串
reverse(res.begin(),res.end());
return res;
}
int main(){
int n;
string s;
cin>>n>>s;
bool flag=false;
for(int i=0;i<=30;i++){
if(check(s)){
printf("STEP=%d\n",i);
flag=true; //找到答案,标记flag
break; //找到答案,就退出循环
}
s=change(s,n);
}
if(flag==false)puts("Impossible!");//未找到答案,按要求输出
return 0;
}