题目链接
题目背景
某涉密单位下发了某种票据,并要在年终全部收回。
题目描述
每张票据有唯一的 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!
文章描述了一道蓝桥杯编程竞赛中的题目,该题目要求找出由于录入错误导致的票据ID断号和重号。解决方案包括使用桶排序法在给定的数据范围内高效地找出断号和重号ID,以及使用普通的排序方法,但后者可能会因时间复杂度较高而导致超时。代码示例展示了两种方法的实现。
835

被折叠的 条评论
为什么被折叠?



