题目描述
某涉密单位下发了某种票据,并要在年终全部收回。
每张票据有唯一的ID号。
全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。
因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另外一个ID重号。
你的任务是通过编程,找出断号的ID和重号的ID。
假设断号不可能发生在最大和最小号。
输入格式
第一行包含整数 N,表示后面共有 N 行数据。
接下来 N 行,每行包含空格分开的若干个(不大于100个)正整数(不大于100000),每个整数代表一个ID号。
输出格式
要求程序输出1行,含两个整数 m,n,用空格分隔。
其中,m表示断号ID, n 表示重号ID。
数据范围
1≤N≤100
样例
blablabla
思路
找出最大和最小的数,同时再用一个数组记录每个数字的个数,最后遍历一遍即可
C++ 代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int M=100010;
int cnt[M];
int main(){
int line,Min=100001,Max=0,a;
int n,m; //m表示断号ID,n表示重号ID
cin>>line;
while(line--){
while(cin>>a){
cnt[a]++;
Max=max(Max,a);
Min=min(Min,a);
}
}
for(int j=Min;j<=Max;j++){
if(cnt[j]==0) m=j;
else if(cnt[j]==2) n=j;
}
cout<<m<<" "<<n<<endl;
return 0;
}
upd:这份代码是多年前刚学c++写的,有些不足之处(这样写导致line是没有用的 但这题对答案是没有影响的
如果要严格按照每行读取数据可以采用getline(cin,s)
的方法先读取整行
然后用sstream
的这种方式来分割,再转成数字(或者遍历字符串手动分割)
下面是sstream
的简易用法
//Example:可以用于分割被空格、制表符等符号分割的字符串
#include<iostream>
#include<sstream> //istringstream 必须包含这个头文件
#include<string>
using namespace std;
int main(){
string str="i am a boy";
istringstream is(str);
string s;
while(is>>s) {
cout<<s<<endl;
}
}
您好,第一种方法最后应该是 j<=Max; 因为最后可能会重号。
是的,已经修改了
感谢
您好,我将您这代码放在dev里面运行,为什么不能终止啊
因为你没有给一个终止指令,退出不了while循环。可以按ctrl+c还是z来着退出程序。具体原因可以网上找找答案。
下面评论也有我之前的回答。
这是因为while(cin>>a)是读到EOF(文件结束标记)循环会终止,而本地编译器要加Ctrl+Z结束(除非你是用freopen的方式
谢谢谢谢,太感谢了
定一个全局数组如果没有数据输入时会等于0;
所以可以用等0这个边界来找出输入多少个数据;
想问一下第二个代码中 while(is>>s) 里的is>>s 是什么意思呢
可以理解为
cin>>s
一样,这里是指将istringstream以空格为间隔读每一个单词upd:这份代码是多年前刚学c++写的,有些不足之处(这样写导致line是没有用的 但这题对答案是没有影响的
如果要严格按照每行读取数据可以采用
getline(cin,s)
的方法先读取整行然后用
sstream
的这种方式来分割,再转成数字(或者遍历字符串手动分割)下面是
sstream
的简易用法不足在于:
while(line--)
注释(去除)掉也是对的#include[HTML_REMOVED]
using namespace std;
typedef struct li{
int base[10001];
int Min;
int Max;
}Sta;
int main(){
int T;
cin>>T;
Sta L;
L.Min=0;
L.Max=1e6;
while(T–){
int num;
char s;
do{
scanf(“%d”,&num);
L.base[num];
if(L.Min>num) L.Min=num;
if(L.Max<num) L.Max=num;
}while((s=getchar())!=’\n’);
}
int a=0;
int b=0;
for(int i=L.Min;i<=L.Max;i){
if(L.base[i]==0) b=i;
if(L.base[i]==2) a=i;
if(a&&b) break;
}
cout<<b<<’ ‘<<a;
}
我这个是自己实现的多组输入,为什么这个不可以啊
难受。。。。。
这里可能是input数据问题 你可以观察到每行数据尾都有空格
请问为什么采用scanf读入的时候不行啊?是在一直输入,这是因为什么
代码看下
采用scanf读入应该是把
while(cin>>a)
改成while(scanf("%d",&a)!=EOF
,不知道你是不是这个问题是的,已经解决了
for循环的时候,下标Min到Max之间cnt都是有值的吗?
因为在读入过程中进行
cnt[a]++
了明白了,谢谢
请问,为什么要开1e5 + 10的数组,题目不是说100行,每行不超过100个吗
因为这里的数组是和数的大小有关,而不是数量。因为cnt[i]数组表示i这个数的数量。如果想优化的话可以考虑map/unordered_map或离散化(大概可以吧
没错,理解错误了,谢了
大佬N好像没有用到(笑哭)
emm确实没有用到(逃
i 好像也是,定义了i 然后后面用了j(逃
这个本地编译器跑完死循环了QAQ
不会吧(逃
是不是你自己数据造错了,导致死循环
真哒QAQ,那个while(cin>>a) 输入空格和换行符号都不会跳出这个循环的,可以用getchar()
这是因为while(cin>>a)是读到EOF(文件结束标记)循环会终止,而本地编译器要加Ctrl+Z结束(除非你是用freopen的方式
ok 感谢
那蓝桥杯比赛写while(cin>>a)会导致编译失败而不通过吗
不会