安徽工程大学校赛题目

概述:
介于有学弟问我题目,并且有些疑问自己在CSDN搜索也不知如何搜索出想要的东西(当然其实都是从初学者过来的,在我自己摸索时,也有遇到过类似情况)。故有此想法,写此题解,与其说是题解,倒不如说给大家分享一些博客与代码,在补题时(正所谓,比赛不补题,等于没比),可以轻松点,第一次用CSDN写东西,不太熟练,或许有些小问题,请多担待。
#第一题
printf语法题,按题目要求输出即可。
#第二题
经典oj第一题a+b,多了个未知测试数据数量来进行读入,虽然是竞赛基本tips,但对于大多数同学来说,可能会不太友好,不过见过一次,学一下,基本也就会了。
多组测试数据介绍 详情见博客添加链接描述

提供给新生C语言的写法

//写法一
#include<stdio.h>

int main(){
	int a,b;
	while(~scanf("%d %d",&a,&b)){
		printf("%dn",a+b);
	} 
	return 0;
} 
//写法二
#include<stdio.h>

int main(){
	int a,b;
	while(scanf("%d %d",&a,&b)!=EOF){
		printf("%dn",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] != '') {			//判断字符串是否到结尾了 
			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 modifiedn");//有个坑点,如果总数是一个人要用is 
		else printf("There are %d accounts and no account is modified", n);//多个人,这里是are 
	}
	else {
		printf("%dn", m);		//打印修改的人数,并遍历输出 
		for (int i = 0; i < m; i++) {
			printf("%s %sn", 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 modifiedn");
		}else{			//多个人,这里是are 
			 printf("There are %d accounts and no account is modified", n);
		}
	}else{
		printf("%dn",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=%dn",i);
			flag=true;	//找到答案,标记flag 
			break;		//找到答案,就退出循环 
		}
		s=change(s,n);
	}
	if(flag==false)puts("Impossible!");//未找到答案,按要求输出 
	return 0;
} 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>