原题链接: AcWing 1204. 错误票据 - AcWinghttps://www.acwing.com/activity/content/code/content/1981205/
思路:
本题思路很简单,把所有输入的数存到数组里,排序,然后遍历一遍就行了。判重的话就开个新数组记录一下每个数的出现次数即可。
本题的难点就在于处理输入,需要对C++语法比较熟悉
做法如下:
- 处理输入的所有数字
- 遍历计数器数组,找到重号
- 遍历一遍排好序的数组,如果不连续且不是重号,那就是断号,记录下来
- 分别输出重号和断号
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int a[N],b[N];
int main()
{
int T;
cin>>T;
int cnt=0;
string s1;
getline(cin,s1);//吸掉回车
while(T--)
{
string s;
getline(cin,s);
for(int i=0;i<s.size();i++)
{
if(isdigit(s[i]))//处理每个数,将其存入a数组
{
int x=0,j=i;
while(j<s.size()&&isdigit(s[j])) x=x*10+s[j++]-'0';
i=j-1;//i别忘跟着走
a[cnt]=x;
b[a[cnt]]++;//计数器,存得是a数组中元素出现的次数
cnt++;
}
}
}
sort(a,a+cnt);
//for(int i=0;i<cnt;i++) cout<<a[i]<<" ";
//cout<<endl;
int m=0;
for(int i=0;i<N;i++)
{
if(b[i]==2)
{
m=i;
break;
}
}
int j=0;
for(int i=0;i<cnt;i++)
{
if(i)
{
int j=i-1;
if(a[j]!=a[i]-1&&a[i]!=m)//不连续,且不是重号
{
cout<<a[i]-1<<" "<<m;
break;
}
}
}
return 0;
}
这里简单讲解一下:
for(int i=0;i<s.size();i++)
{
if(isdigit(s[i]))
{
int x=0,j=i;
while(j<s.size()&&isdigit(s[j])) x=x*10+s[j++]-'0';
i=j-1;//i别忘跟着走
a[cnt]=x;
b[a[cnt]]++;
cnt++;
}
}
由于s数组存的是单个字符,而有的数可能是很多位,所以对于连续的数字段就要逐个计算,再将最后算出的那个数存入a数组,又因为是从左往右遍历,所以设个x=0,每次*10+s[i],直到当前数字段全部处理完毕。举个例子,假如s[1]==' ',s[2]==1,s[3]==5,s[4]==3,s[5]==' ',则x=0*10+1 --> x=1*10+5 -->x=15*10+3 -->x==153
这样就可以将整数153存入a数组,而不是将1、5、3分别存入数组。
作者:机械之忍
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
本人刚开始写题解不久,很多地方还不成熟,为了让读者更好的理解思路和细节,我做这道题时的调试代码片段也保留了,我觉得这样能更直观的表达我的想法,如果各位有疑问之处,或者我写的哪里有错误,欢迎私信我或者在下方留言
我的QQ:2907065305