蓝桥杯 错误票据

原题链接: 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值