【[蓝桥杯 2013 省 AB] 错误票据】

文章描述了一道蓝桥杯编程竞赛中的题目,该题目要求找出由于录入错误导致的票据ID断号和重号。解决方案包括使用桶排序法在给定的数据范围内高效地找出断号和重号ID,以及使用普通的排序方法,但后者可能会因时间复杂度较高而导致超时。代码示例展示了两种方法的实现。
摘要由CSDN通过智能技术生成


题目链接

题目背景

某涉密单位下发了某种票据,并要在年终全部收回。

题目描述

每张票据有唯一的 ID 号,全年所有票据的 ID 号是连续的,但 ID 的开始数码是随机选定的。因为工作人员疏忽,在录入 ID 号的时候发生了一处错误,造成了某个 ID 断号,另外一个 ID 重号。

你的任务是通过编程,找出断号的 ID 和重号的 ID。

数据保证断号不可能发生在最大和最小号。

输入格式

一个整数 N(N<100) 表示后面数据行数,接着读入 N 行数据,每行数据长度不等,是用空格分开的若干个(不大于 100 个)正整数(不大于 105),每个整数代表一个 ID 号。

输出格式

要求程序首先输入1行,含俩个整数m,n,用空格分隔,其中,m表示断号ID,n表示重号ID。

输入输出样例

sample #1
输入

2
5 6 8 11 9
10 12 9

输出

7 9

sample #2

输入

2
5 6 8 11 9
10 12 9

输出

7 9

解题思路

题目的意思就是将n行数进行字进行排序来查找出段号ID,和重号ID,题目保证段号不发生在最大号和最小号。常规思路就是将n行数排序好再从小到大寻找断号和重号ID。
数据范围:n(<=100)行,每行不多于 100个,ID不大于105

最优思路(桶排序)

看见数据范围都比较小,只有105的大小,查找这个数是否出现或者出现多次,用桶排序进行最好。
看见题目有n行,在c里面可以用scanf()!=EOF来表示没读入文件末尾,对桶排序来说基本上相当于无用数据,所以直接读入就行。
桶排序后,开始遍历最小ID到最大ID进行判断,如果i为断层则,a[i]=0,i为重数的话,a[i]>1;
下面是ac的代码:

#include<iostream>
#include<string.h>
const int N=1e5+5;
int a[N],n,_;
int min=2*N,max=0;//最大最小值定义一定要记得给好初始化
void solve() {
	std::cin>>n;//读入n行
	
	while(std::cin>>_) {//在c++里面读到末尾就会结束
		a[_]++;//桶排序
		max=std::max(_,max);//求所有数的最大值,最大值函数
		min=std::min(_,min);//求所有数的最小值,最小值函数
	}
	
	int duan,chong;//求断数,重数
	for(int i=min; i<=max; ++i) {//遍历区间
		if(a[i]==0) duan=i;//找断数
		if(a[i]>1) chong=i;//找重数
	}
	std::cout<<duan<<" "<<chong;//输出
}
int main() {
//快速读入
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);

	solve();

	return 0;
}

普通排序求解(o(n2)会超时,记得用排序函数)

普通做法就是排好序,把数组遍历一次就行。题目保证断数不在开头结尾如果一个数是断层的那么a[i]-a[i-1]=2;a[i]-1为断数;重数就 是 a[i]=a[i-1];
思路就是这样,下面是代码:

#include<iostream>
#include<algorithm>
const int N=1e5+5;
int n,a[N],cnt,duan,chong,t;
void solve(){
	std::cin>>n;
	while(std::cin>>t){
	    a[cnt++]=t;
	}
	std::sort(a,a+cnt);//自带的排序
	for(int i=1;i<cnt;++i){
	    if(a[i]-a[i-1]>1) duan=a[i]-1;
	    if(a[i]==a[i-1])  chong=a[i];
	}
	std::cout<<duan<<" "<<chong;
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);

	solve();

	return 0;
}

GOOD LUCK! HAVE FUN!

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值