P8598 [蓝桥杯 2013 省 AB] 错误票据 题解

· · 题解

题意简析

给定一个序列,找这个序列的值域中出现两次的数和没出现的数。思路很简单,排序之后扫一遍即可,这里主要讲如何正确输入(此处“正确输入”指在输入合法的情况下不需要手动输入 EOF 字符)。

这里给出了行数,显然我们可以想到使用字符串按行读入,如 C++ 风格的 string 字符串,我们就可以用 getline 读入一行。那么如何把 string 中不定数量的 int 提取并存入数组呢?我们可以使用 stringstream 定义一个字符串流,然后就可以像 cin 一样提取数字了。对于不定数量,也如同 cin 中读到 EOF 就停止读入那样,stringstream 会在字符串结束时停止读入。对于 C 风格的 char* 字符串,sscanf 也有类似用法,不再赘述。

由于本题涉及 cingetline 混用,因此需要使用 cin.ignore(numeric_limits<streamsize>::max(),'\n'); 来提取第一行的换行符,并将流指针移动到下一行。

代码/解释


#include<bits/stdc++.h>
using namespace std;
int a[10001],l;
int main()
{
    int N,m,n,i;
    string s;
    cin>>N;
    cin.ignore(numeric_limits<streamsize>::max(),'\n');
    for(i=1;i<=N;i++)
    {
        getline(cin,s);
        stringstream sin(s);
        while(sin>>a[++l]);
    }
    sort(a+1,a+l+1);
    for(i=2;i<=l;i++)
    if(a[i]==a[i+1]-2) m=a[i]+1;
    else if(a[i]==a[i+1]) n=a[i];
    printf("%d %d\n",m,n);
    return 0;
}