东华oj-进阶题第40题-按要求输出序列

在这里插入图片描述

40 按要求输出序列

作者: 孙辞海 时间限制: 10S章节: 一维数组

问题描述 :

明明的爸爸是一位著名的数学家。他在明明很小的时候就发现明明有过人的数学天赋,因此有意培养他对数学的兴趣。一次,明明的爸爸为了培养明明对数字的敏感,和明明玩起了一个数字游戏,这个游戏的名称叫“按要求输出序列”。在游戏中,明明的爸爸给了明明一串数字,要求明明首先把这串数字中重复出现的数字删除到仅剩一个,即相同的数字只保留一个,然后将这串数字从小到大进行排序。明明很快就理解了游戏的规则,开始玩起来。明明的爸爸首先给了明明三个数字:3、2、1;明明很快就回答说:“1、2、3”。明明的爸爸惊讶于明明的反应能力,开始加大游戏的难度,给出了由6个数字组成的数字串:2、1、4、3、5、2;明明眼珠子一转,脱口而出:“1、2、3、4、5”(由于“2”出现了两次,因此要删除一个,然后再排序输出。)。明明的爸爸意识到简单的数字串难不住明明,于是决定给出很长的一串数字串来考明明。但与此同时,明明爸爸面对这很长的数字串也无法一时计算出最后的结果,于是就求助于你,让你帮他写一个程序,用来计算出数字串最后的结果。

明明的爸爸的问题可以归结为:给你一个数字串,里面有n个数字,首先对数字串中的数字进行处理,删除重复出现的数字(重复出现的数字只保留一个),然后对数字串从小到大进行排序,最后输出排序后的字符串。
输入说明 :

你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据占两行:

第一行是一个正整数n(1≤n≤200),表示数字串中有n个数字,

第二行是n个数字,n个数字都大于等于0且小于等于109,每两个数字用一个空格隔开。

每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。 输出说明 :

对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一个排序后的数字串,数字串中的数字用一个空格隔开。每组运算结果单独形成一行数据,其行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间没有任何空行,第一组运算结果前面以及最后一组运算结果后面也都没有任何空行。
注:通常,显示屏为标准输出设备。 输入范例 : 5 4 2 2 6 6 9 76 19 1 2 55 37 38 55 76
输出范例 : 2 4 6 1 2 19 37 38 55 76

代码:

/*
	T40 按要求输出序列 
*/ 

#include<stdio.h> 
#define MAX_SIZE 205

void sort(int nums[], int n);
void removeDupl(int nums[], int n);

int main() {
	int n = 0;
	int i = 0;
	int temp = 0;
	int nums[MAX_SIZE] = {0};
	
	while (scanf("%d", &n) != EOF) {
		temp = 0;
		for (i = 0; i < n; i++)
			scanf("%d", &nums[i]);
			
		sort(nums, n);// 排序	
		removeDupl(nums, n);// 去重 
		for (i = 0; i < n; i++) {
			if (nums[i] != -1) {
				temp++;
				if (temp == 1)
					printf("%d", nums[i]);
				else
					printf(" %d", nums[i]);
			}
		} 	
		printf("\n");
	}
	
	return 0;
} 

// 排序
void sort(int nums[], int n) {
	int i = 0, j = 0;
	int temp = 0;
	
	for (i = n - 1; i > 0; i--) {
		for (j = 0; j < i; j++) {
			if (nums[j] > nums[j + 1]) {
				temp = nums[j];
				nums[j] = nums[j + 1];
				nums[j + 1] = temp; 
			}
		}
	}	
} 

// 去重
void removeDupl(int nums[], int n) {
	int i = 0, j = 0;
	
	for (i = 0; i < n - 1; i++) {
		while (nums[i] == nums[i + 1]) {// 相邻两数相等,则删除前者 
			for (j = i; j < n; j++) 
				nums[j] = nums[j + 1]; 
			nums[n - 1] = -1;
			n--; 
		}
	}
} 

这个去重代码复杂度有点高,我搜了下去重,看到了更好的去重算法,如下:

// 去重
void removeDupl(int nums[], int n) {
	int i = 0, j = 0;
	int count = 0;
	
	for (i = 0; i < n - 1; i++) {
		if (nums[i] != nums[i + 1]) {// 将不同的数字记下来即可 
			nums[count++] = nums[i];
		} 
	}
	nums[count] = nums[n - 1];// 最后一个数字 
	for (i = count + 1; i < n; i++) {// 置特殊数字 
		nums[i] = -1;
	} 
} 

虽然过程多了些,但是复杂度降下来了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值