题目描述
某涉密单位下发了某种票据,并要在年终全部收回。
每张票据有唯一的 ID 号。全年所有票据的 ID 号是连续的,但 ID 的开始数码是随机选定的。
因为工作人员疏忽,在录入 ID 号的时候发生了一处错误,造成了某个 ID 断号,另外一个 ID 重号。
你的任务是通过编程,找出断号的 ID 和重号的 ID 。
假设断号不可能发生在最大和最小号。
输入
要求程序首先输入一个整数 N ( N < 100 ) N\ (N<100) N (N<100)表示后面数据行数。
接着读入 N 行数据。
每行数据长度不等,是用空格分开的若干个(不大于 100 个)正整数(不大于 1 0 5 10^5 105 )。
2
5 6 8 11 9
10 12 9
输出
要求程序输出 1 行,含两个整数 m,n,用空格分隔。
其中,m 表示断号 ID,nn 表示重号 ID。
7 9
解法一
这题比较恶心的地方是以行读入,但是没有说这一行到底有多少个
我们采用的解决方案是getline()
行读入stringstream
,再利用stringstream
对象读入到数组中
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n;
int a[110];
bool st[N];
int main() {
int cnt;
cin >> cnt;
string line;
cin.get();
while (cnt--) {
getline(cin, line);
stringstream ssin(line); //将一行的值传入stringstream
while(ssin >> a[n]) { // 再把stringstream当作cin读入
n++;
}
}
int res1, res2; // 重号,断号
for (int i = 0; i < n; i++) {
if (st[a[i]]) res1= a[i]; // 这里即使搜到重号,也不能提前退出
st[a[i]] = true; // 因为要标记出现过的数字
}
int start = 0;
while (!st[start]) start++;
for (int i = start; ; i++) {
if (!st[i]) { // 若出现空缺,则代表断号
res2 = i;
break;
}
}
cout << res2 << ' ' << res1 << endl;
return 0;
}
解决二:排序
将读入的数组进行排序,排序后的数组判断重号断号将很容易
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n;
int a[110];
int main() {
int cnt;
cin >> cnt;
string line;
cin.get();
while (cnt--) {
getline(cin, line);
stringstream ssin(line);
while(ssin >> a[n]) {
n++;
}
}
sort(a, a+n);
int chong, duan;
for(int i = 1; i < n; i++) {
if (a[i] == a[i-1]) chong = a[i];
if (a[i] >= a[i-1] + 2) duan = a[i]-1;
}
cout << duan << ' ' << chong << endl;
return 0;
}