信息学奥赛一本通 做题记录

我使用的语言:C++
题目链接:https://ybt.ssoier.cn/problem_list.php?page=

1204:爬楼梯

【题目描述】
树老师爬楼梯,他可以每次走1级或者2级,输入楼梯的级数,求不同的走法数。
例如:楼梯一共有3级,他可以每次都走一级,或者第一次走一级,第二次走两级,也可以第一次走两级,第二次走一级,一共3种方法。

【输入】
输入包含若干行,每行包含一个正整数N,代表楼梯级数,1≤N≤30。

【输出】
不同的走法数,每一行输入对应一行输出。

【输入样例】
5
8
10

【输出样例】
8
34
89

知识点:输入数据的处理

一次运行,要输入多组数据,直到读至输入文件末尾(EOF)为止:while(cin>>n)

我的代码:

#include <iostream>
using namespace std;
int f(int n){
	if(n==1) return 1;
	if(n==2) return 2;
    return f(n-1)+f(n-2);
}
int main(){
	int n;
	while(cin>>n){
		int res=f(n);
		cout<<res<<endl;
	}
	return 0;
} 

在这里插入图片描述

2046:【例5.15】替换字母

【题目描述】
在应用计算机编辑文档的时候,我们经常遇到替换任务。如把文档中的“电脑”都替换成“计算机”。现在请你编程模拟一下这个操作。

【输入】
输入两行内容,第1行是原文(长度不超过200个字符),第2行包含以空格分隔的两个字符A和B,要求将原文中所有的字符A都替换成字符B,注意:区分大小写字母。

【输出】
一行,输出替换后的结果。

【输入样例】
I love China. I love Beijing.
I U

【输出样例】
U love China. U love Beijing.

我的代码:

#include <iostream>
using namespace std;
int main() {
    string s;
    getline(cin,s);
    char a,b;
    cin>>a>>b;
    for(int i=0;i<s.size();i++){
    	if(s[i]==a) cout<<b;
    	else cout<<s[i];
	}
    return 0;
}

在这里插入图片描述

2047:【例5.16】过滤空格

【题目描述】
过滤多余的空格。一个句子中也许有多个连续空格,过滤掉多余的空格,只留下一个空格。

【输入】
一行,一个字符串(长度不超过200),句子的头和尾都没有空格。

【输出】
过滤之后的句子。

【输入样例】
Hello world.This is c language.

【输出样例】
Hello world.This is c language.

我的代码:

#include <iostream>
using namespace std;
int main() {
	string s;
	while(cin>>s){
		cout<<s<<" ";
	} 
    return 0;
}

在这里插入图片描述

2048:【例5.18】串排序

【题目描述】
对给定的n(1≤n≤20)个国家名(国家名字长度不超过20),按其字母的顺序输出。

【输入】
第一行为国家的个数n;
以下n行为国家的名字。

【输出】
n
行,排序后的国名。

【输入样例】
3
Korea
China
Japan

【输出样例】
China
Japan
Korea

我的代码1:string字符串,用sort排序

#include<iostream>
#include<algorithm>
using namespace std;
int main() {
	int n;
	cin>>n;
	string name[25];
	for(int i=0;i<n;i++){
		cin>>name[i];
	}
	sort(name,name+n);
	for(int i=0;i<n;i++){
		cout<<name[i]<<endl;
	}
    return 0;
}

在这里插入图片描述
我的代码2:字符数组,不用sort,手写冒泡排序。

#include<iostream>
#include<cstring>
using namespace std;
int main() {
	int n;
	cin>>n;
	char name[25][25];
	for(int i=0;i<n;i++){
		cin>>name[i];
	}
	for(int i=0;i<n-1;i++){
		for(int j=i+1;j<n;j++){
			if(strcmp(name[i],name[j])>0){
				char k[25];
				strcpy(k,name[i]);
				strcpy(name[i],name[j]);
				strcpy(name[j],k);
			}
		}	
	}
	for(int i=0;i<n;i++){
		puts(name[i]);
	}
    return 0;
}

在这里插入图片描述

2049:【例5.19】字符串判等

【题目描述】
判断两个由大小写字母和空格组成的字符串在忽略大小写,且忽略空格后是否相等。

【输入】
两行,每行包含一个字符串。

【输出】
若两个字符串相等,输出YES,否则输出NO。

【输入样例】
a A bb BB ccc CCC
Aa BBbb CCCccc

【输出样例】
YES

我的代码1:一边处理一边判断。遇到空格跳过,字符串s1转成大小写和字符串s2一样。

#include<iostream>
using namespace std;
int main() {
	string s1,s2;
	getline(cin,s1);
	getline(cin,s2);
	int j1,j2=0;
	while(1){
		while(j1<=s1.size()&&s1[j1]==' '){	//遇到空格跳过
			j1++;
		}
		while(j2<=s2.size()&&s2[j2]==' '){
			j2++;
		}
		if(j1>s1.size() || j2>s2.size()) break;	//遍历超出范围跳过
		if(s1[j1]<s2[j2]) s1[j1]+='a'-'A';	//字符串s1大写转小写
		else if(s1[j1]>s2[j2]) s1[j1]+='A'-'a';	//字符串s1小写转大写
		if(s1[j1]!=s2[j2]){
			cout<<"NO";
			return 0;
		}	
		j1++;
		j2++;
	}
	cout<<"YES";
    return 0;
}

在这里插入图片描述
我的代码2:先处理后判断。s1,s2统一删除空格并转成小写,再判断是否相等。

#include<iostream>
#include<string>
using namespace std;
int main() {
	string s1,s2;
	getline(cin,s1);
	getline(cin,s2);
	for(int i=0;i<s1.size();i++){	//处理s1字符串 
		if(s1[i]==' '){		//删除空格 
			s1.erase(i,1);
			i--;	//易漏 
		}else if(s1[i]>='A' && s1[i]<='Z'){		//统一转换成小写 
			s1[i]+='a'-'A';
		}
	}
	for(int i=0;i<s2.size();i++){	//处理s2字符串
		if(s2[i]==' '){
			s2.erase(i,1);
			i--;
		}else if(s2[i]>='A' && s2[i]<='Z'){
			s2[i]+='a'-'A';
		}
	}
	if(s1==s2) cout<<"YES";
	else cout<<"NO";
    return 0;
}

在这里插入图片描述

2050:【例5.20】字串包含

【题目描述】
字符串移位包含问题。
对于一个字符串来说,定义一次循环移位操作为:将字符串的第一个字符移动到末尾形成新的字符串。
给定两个字符串s1和s2,要求判定其中一个字符串是否是另一字符串通过若干次循环移位后的新字符串的子串。例如CDAA是由AABCD两次移位后产生的新串BCDAA的子串,而ABCD与ACBD则不能通过多次移位来得到其中一个字符串是新串的子串。

【输入】
一行,包含两个字符串,中间由单个空格隔开。字符串只包含字母和数字,长度不超过30。

【输出】
如果一个字符串是另一字符串通过若干次循环移位产生的新串的子串,则输出true,否则输出false。

【输入样例】
AABCD CDAA

【输出样例】
true

知识点:s.find()没找到返回值

s2.find(s1)==string::npos是npos而不是NULL

我的代码:

#include<iostream>
#include<string>
using namespace std;
int main() {
	string s1,s2,s3;
	cin>>s1>>s2;
	if(s1.size()>s2.size()) {	//交换s1和s2 
		s3=s1;
		s1=s2;
		s2=s3;
	}
	s2+=s2;
	if(s2.find(s1)==string::npos) cout<<"false";
	else cout<<"true";
    return 0;
}

在这里插入图片描述

1839:【05NOIP提高组】谁拿了最多奖学金

【题目描述】
某校的惯例是在每学期的期末考试之后发放奖学金。发放的奖学金共有五种,获取的条件各自不同:
1)院士奖学金,每人8000元,期末平均成绩高于80分(>80),并且在本学期内发表1篇或1篇以上论文的学生均可获得;
2)五四奖学金,每人4000元,期末平均成绩高于85分(>85),并且班级评议成绩高于80分(>80)的学生均可获得;
3)成绩优秀奖,每人2000元,期末平均成绩高于90分(>90)的学生均可获得;
4)西部奖学金,每人1000元,期末平均成绩高于85分(>85)的西部省份学生均可获得;
5)班级贡献奖,每人850元,班级评议成绩高于80分(>80)的学生干部均可获得;

只要符合条件就可以得奖,每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。例如姚林的期末平均成绩是87分,班级评议成绩82分,同时他还是一位学生干部,那么他可以同时获得五四奖学金和班级贡献奖,奖金总数是4850元。

现在给出若干学生的相关数据,请计算哪些同学获得的奖金总数最高(假设总有同学能满足获得奖学金的条件)。

【输入】
第一行是一个整数N(1 <= N <= 100),表示学生的总数。接下来的N行每行是一位学生的数据,从左向右依次是姓名,期末平均成绩,班级评议成绩,是否是学生干部,是否是西部省份学生,以及发表的论文数。姓名是由大小写英文字母组成的长度不超过20的字符串(不含空格);期末平均成绩和班级评议成绩都是0到100之间的整数(包括0和100);是否是学生干部和是否是西部省份学生分别用一个字符表示,Y表示是,N表示不是;发表的论文数是0到10的整数(包括0和10)。每两个相邻数据项之间用一个空格分隔。

【输出】
三行,第一行是获得最多奖金的学生的姓名,第二行是这名学生获得的奖金总数。如果有两位或两位以上的学生获得的奖金最多,输出他们之中在输入文件中出现最早的学生的姓名。第三行是这N个学生获得的奖学金的总数。

【输入样例】
4
YaoLin 87 82 Y N 0
ChenRuiyi 88 78 N Y 1
LiXin 92 88 N N 0
ZhangQin 83 87 Y N 1

【输出样例】
ChenRuiyi
9000
28700

我的代码:这题容易看错题目,班级贡献奖是班级评议成绩高于80分而不是期末平均成绩高于80分。看错这个条件写出来的代码能通过题目给出的样例,导致这题部分正确,卡了我很久。

#include<iostream>
using namespace std;
int main() {
	int n;
	cin>>n;
	int maxMoney=-10,sumMoney=0;
	string maxName;
	while(n--){
		string name;
		int score,classScore,paper;
		char isStudent,isWest;
		int money=0;
		cin>>name>>score>>classScore>>isStudent>>isWest>>paper;
		if(score>80 && paper>=1) money+=8000;
		if(score>85 && classScore>80) money+=4000;
		if(score>90) money+=2000;
		if(score>85 && isWest=='Y') money+=1000;
		if(classScore>80 && isStudent=='Y') money+=850;
		sumMoney+=money;
		if(money>maxMoney){
			maxMoney=money;
			maxName=name;
		}
	} 
	cout<<maxName<<endl<<maxMoney<<endl<<sumMoney;
    return 0;
}

在这里插入图片描述

1129:统计数字字符个数

【题目描述】
输入一行字符,统计出其中数字字符的个数。

【输入】
一行字符串,总长度不超过255。

【输出】
输出为1行,输出字符串里面数字字符的个数。

【输入样例】
Peking University is set up at 1898.

【输出样例】
4

我的代码:

#include<iostream>
using namespace std;
int main() {
	string s;
	getline(cin,s);
	int sum=0;
	for(int i=0;i<s.size();i++){
		if(s[i]<='9' && s[i]>='0'){
			sum++;
		}
	}
	cout<<sum;
    return 0;
}

在这里插入图片描述

1130:找第一个只出现一次的字符

【题目描述】
给定一个只包含小写字母的字符串,请你找到第一个仅出现一次的字符。如果没有,输出no。

【输入】
一个字符串,长度小于100000。

【输出】
输出第一个仅出现一次的字符,若没有则输出no。

【输入样例】
abcabd

【输出样例】
c

我的代码:

#include<iostream>
using namespace std;
int count[30];
int main() {
	string s;
	getline(cin,s);
	for(int i=0;i<s.size();i++){
		count[s[i]]++;
	}
	bool flag=true;
	for(int i=0;i<s.size();i++){
		if(count[s[i]]==1){
			cout<<s[i];
			flag=false;
			break;
		}
	}
	if(flag==true)	cout<<"no";
    return 0;
}

在这里插入图片描述

1131:基因相关性

【题目描述】
为了获知基因序列在功能和结构上的相似性,经常需要将几条不同序列的DNA进行比对,以判断该比对的DNA是否具有相关性。
现比对两条长度相同的DNA序列。定义两条DNA序列相同位置的碱基为一个碱基对,如果一个碱基对中的两个碱基相同的话,则称为相同碱基对。接着计算相同碱基对占总碱基对数量的比例,如果该比例大于等于给定阈值时则判定该两条DNA序列是相关的,否则不相关。

【输入】
有三行,第一行是用来判定出两条DNA序列是否相关的阈值,随后2行是两条DNA序列(长度不大于500)。

【输出】
若两条DNA序列相关,则输出“yes”,否则输出“no”。

【输入样例】
0.85
ATCGCCGTAAGTAACGGTTTTAAATAGGCC
ATCGCCGGAAGTAACGGTCTTAAATAGGCC

【输出样例】
yes

我的代码:

#include<iostream>
using namespace std;
int count[30];
int main() {
	double c;
	string s1,s2;
	cin>>c>>s1>>s2;
	double same=0;
	for(int i=0;i<s1.size();i++){
		if(s1[i]==s2[i]) same++;
	}
	double res=same/s1.size();
	if(res<c) cout<<"no";
	else cout<<"yes";
    return 0;
}

在这里插入图片描述

1132:石头剪子布

【题目描述】
石头剪子布,是一种猜拳游戏。起源于中国,然后传到日本、朝鲜等地,随着亚欧贸易的不断发展它传到了欧洲,到了近现代逐渐风靡世界。简单明了的规则,使得石头剪子布没有任何规则漏洞可钻,单次玩法比拼运气,多回合玩法比拼心理博弈,使得石头剪子布这个古老的游戏同时用于“意外”与“技术”两种特性,深受世界人民喜爱。

游戏规则:石头打剪刀,布包石头,剪刀剪布。

现在,需要你写一个程序来判断石头剪子布游戏的结果。

【输入】
第一行是一个整数N,表示一共进行了N次游戏。1≤N≤100。
接下来N行的每一行包括两个字符串,表示游戏参与者Player1,Player2的选择(石头、剪子或者是布):
S1 S2
字符串之间以空格隔开,S1,S2只可能取值在{“Rock”, “Scissors”, “Paper”}(大小写敏感)中。

【输出】
输出包括N行,每一行对应一个胜利者(Player1或者Player2),或者游戏出现平局,则输出Tie。

【输入样例】
3
Rock Scissors
Paper Paper
Rock Paper

【输出样例】
Player1
Tie
Player2

我的代码:

#include<iostream>
using namespace std;
int main() {
	int n;
	cin>>n;
	while(n--){
		string s1,s2;
		cin>>s1>>s2;
		if(s1=="Rock"&&s2=="Scissors" || s1=="Scissors"&&s2=="Paper" || s1=="Paper"&&s2=="Rock") cout<<"Player1"<<endl;
		else if(s2=="Rock"&&s1=="Scissors" || s2=="Scissors"&&s1=="Paper" || s2=="Paper"&&s1=="Rock") cout<<"Player2"<<endl;
		else cout<<"Tie"<<endl;
	}
    return 0;
}

在这里插入图片描述

选择排序模板题

题目链接:https://www.luogu.com.cn/problem/U230326

题目背景
选择排序,时间复杂度(平均) O ( n 2 ) O(n^2) O(n2),时间复杂度(最坏) O ( n 2 ) O(n^2) O(n2),时间复杂度(最好) O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1),稳定性:稳定
选择排序( S e l e c t i o n − s o r t Selection-sort Selectionsort)是一种简单直观的排序算法。它的工作原理是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置;然后,再从剩余未排序的元素中继续寻找最小(大)元素,然后放到已排序序列的最末尾。以此类推,直到所有元素均排序完毕。

题目描述
给你一个正整数 n n n n n n个正整数 a 1 a_1 a1~ a n a_n an(无序),请将其用选择排序排序,并输出该数组排序后的结果。

输入格式
第一行: n n n
第二行: a i a_i ai~ a n a_n an

输出格式
第一行:排序后的 a 1 a_1 a1~ a n a_n an

样例输入1

5
5 3 6 8 3

样例输出1

3 3 5 6 8

提示
10 ≤ n ≤ 800 10 \leq n \leq 800 10n800
1 ≤ a i ≤ 1 0 4 1 \leq a_i \leq 10^4 1ai104

我的代码:一本通的书上有这一题,但是oj上没有,反而被我在洛谷找到了差不多的模版题。

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	int a[10005];
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	for(int i=0;i<n-1;i++){
		int min=i;
		for(int j=i;j<n;j++){
			if(a[min]>a[j]) min=j;
		}
		swap(a[i],a[min]);
	}
	for(int i=0;i<n;i++){
		cout<<a[i]<<" ";
	}
	return 0; 
}
 

在这里插入图片描述

冒泡排序模板题

题目链接:https://www.luogu.com.cn/problem/U230342

题目背景
冒泡排序,时间复杂度(平均) O ( n 2 ) O(n^2) O(n2),时间复杂度(最坏) O ( n 2 ) O(n^2) O(n2),时间复杂度(最好) O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1),稳定性:稳定
冒泡排序( B u b b l e − s o r t Bubble-sort Bubblesort)是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较相邻的两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有元素的顺序出现错误,也就是说该数列已经排序完成,这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,如同泡泡。

题目描述
给你一个正整数 n n n n n n个正整数 a 1 a_1 a1~ a n a_n an(无序),请将其用冒泡排序排序,并输出该数组排序后的结果。

输入格式
第一行: n n n
第二行: a i a_i ai~ a n a_n an

输出格式
第一行:排序后的 a 1 a_1 a1~ a n a_n an

样例输入1

5
5 3 6 8 3

样例输出1

3 3 5 6 8

提示
10 ≤ n ≤ 800 10 \leq n \leq 800 10n800
1 ≤ a i ≤ 1 0 4 1 \leq a_i \leq 10^4 1ai104

我的代码1:一本通上的代码是错的,for(int j=0;j<i;j++)是j<i而不是j<=i

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	int a[10005];
	for(int i=0;i<n;i++){
		cin>>a[i];
	} 
	for(int i=n-1;i>0;i--){
		for(int j=0;j<i;j++){
			if(a[j]>a[j+1]) swap(a[j],a[j+1]);
		}
	}
	for(int i=0;i<n;i++){
		cout<<a[i]<<" ";
	} 
	return 0;
} 

在这里插入图片描述
我的代码2:i和j都从小到大遍历

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	int a[10005];
	for(int i=0;i<n;i++){
		cin>>a[i];
	} 
	for(int i=0;i<n;i++){
		for(int j=0;j<n-i-1;j++){
			if(a[j]>a[j+1]) swap(a[j],a[j+1]);
		}
	}
	for(int i=0;i<n;i++){
		cout<<a[i]<<" ";
	} 
	return 0;
} 

在这里插入图片描述

1310:【例2.2】车厢重组

【题目描述】
在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转180度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他退休后,火车站决定将这一工作自动化,其中一项重要的工作是编一个程序,输入初始的车厢顺序,计算最少用多少步就能将车厢排序。

【输入】
有两行数据,第一行是车厢总数N(不大于10000),第二行是N个不同的数表示初始的车厢顺序。

【输出】
一个数据,是最少的旋转次数。

【输入样例】
4
4 3 2 1

【输出样例】
6

我的代码1:冒泡排序计算交换次数

#include<iostream>
using namespace std;
int main(){
	int n,res=0;
	cin>>n;
	int a[10005];
	for(int i=0;i<n;i++){
		cin>>a[i];
	} 
	for(int i=n-1;i>0;i--){
		for(int j=0;j<i;j++){
			if(a[j]>a[j+1]){
				swap(a[j],a[j+1]);
				res++;
			} 
		}
	}
	cout<<res;
	return 0;
} 

在这里插入图片描述
我的代码2:i和j都从小到大遍历

#include<iostream>
using namespace std;
int main(){
	int n,res=0;
	cin>>n;
	int a[10005];
	for(int i=0;i<n;i++){
		cin>>a[i];
	} 
	for(int i=0;i<n;i++){
		for(int j=0;j<n-1-i;j++){
			if(a[j]>a[j+1]){
				swap(a[j],a[j+1]);
				res++;
			} 
		}
	}
	cout<<res;
	return 0;
} 

在这里插入图片描述

插入排序模板题

题目链接:https://www.luogu.com.cn/problem/U244852

题目背景
插入排序,时间复杂度(平均) O ( n 2 ) O(n^2) O(n2),时间复杂度(最坏) O ( n 2 ) O(n^2) O(n2),时间复杂度(最好) O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1),稳定性:稳定
插入排序( I n s e r t i o n − S o r t Insertion-Sort InsertionSort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序的数据,在已排序序列中从后向前扫描,找到相应位置并插入。

题目描述
给你一个正整数 n n n n n n个正整数 a 1 a_1 a1~ a n a_n an(无序),请将其用插入排序排序,并输出该数组排序后的结果。

输入格式
第一行: n n n
第二行: a i a_i ai~ a n a_n an

输出格式
第一行:排序后的 a 1 a_1 a1~ a n a_n an

样例输入

5
5 3 6 8 3

样例输出

3 3 5 6 8

提示
10 ≤ n ≤ 800 10 \leq n \leq 800 10n800
1 ≤ a i ≤ 1 0 4 1 \leq a_i \leq 10^4 1ai104

我的代码:一本通上的太麻烦了,还是其他的模版好。

参考链接:https://www.acwing.com/blog/content/8936/

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	int a[10005];
	for(int i=0;i<n;i++){
		cin>>a[i];
	} 
	for(int i=1;i<n;i++){	//i相当于一个分界线,小于i的都是排好序的,插入a[i]
		if(a[i-1]>a[i]){	//需要往a数组中间插入a[i] 
			int temp=a[i];
			int j;
			for(j=i-1;j>=0 && a[j]>temp;j--){	//大于a[i]的数据向后移 
				a[j+1]=a[j];
			}
			a[j+1]=temp;
		} 
	}
	for(int i=0;i<n;i++){
		cout<<a[i]<<" ";
	} 
	return 0;
} 

在这里插入图片描述

【模板】桶排序

题目链接:https://www.luogu.com.cn/problem/U322215

题目描述
输入n个数,将它们从小到大排序。

输入格式
第一行一个数n,表示需要排序的数组的大小。
第二行n个数,表示需要排序的数。

输出格式
一行n个数,表示排好序的数组。

样例输入

5
1 5 4 2 3

样例输出

1 2 3 4 5

提示
对于100%的数据,n≤200000,需要排序的数在区间[1,10]内。

我的代码:

#include<iostream>
#include<cstring>
using namespace std;
int main(){
	int n,k;
	cin>>n;
	int a[15];
	memset(a,0,sizeof(a));
	for(int i=0;i<n;i++){
		cin>>k;
		a[k]++;
	}
	for(int i=0;i<15;i++){
		while(a[i]){
			cout<<i<<" ";
			a[i]--;
		}		
	}
	return 0; 
}
 

在这里插入图片描述

1184、1934:【06NOIP普及组】明明的随机数

【题目描述】
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

【输入】
有2行,第1行为1个正整数,表示所生成的随机数的个数:N;
第2行有N个用空格隔开的正整数,为所产生的随机数。

【输出】
也是2行,第1行为1个正整数M,表示不相同的随机数的个数。第2行为M个用空格隔开的正整数,为从小到大排好序的不相同的随机数。

【输入样例】
10
20 40 32 67 40 20 89 300 400 15

【输出样例】
8
15 20 32 40 67 89 300 400

我的代码:

#include<iostream>
#include<cstring>
using namespace std;
int main(){
	int n,k,len=0;
	cin>>n;
	int a[1005];
	int b[105];
	memset(a,0,sizeof(a));
	for(int i=0;i<n;i++){
		cin>>k;
		a[k]++;
	} 
	for(int i=0;i<1005;i++){
		if(a[i]){
			b[len]=i;
			len++;
		}
	}
	cout<<len<<endl;
	for(int i=0;i<len;i++){
		cout<<b[i]<<" ";
	}
	return 0; 
}

在这里插入图片描述
参考代码:更好,在输入数据的时候就进行处理,更省时间和空间

#include<iostream>
#include<cstring>
using namespace std;
int main(){
	int n,k,len=0;
	cin>>n;
	int a[1005];
	memset(a,0,sizeof(a));
	for(int i=0;i<n;i++){
		cin>>k;
		if(a[k]==0) len++; 
		a[k]++;
	} 
	cout<<len<<endl;
	for(int i=0;i<1005;i++){
		if(a[i]) cout<<i<<" ";
	}
	return 0; 
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值