牛客c++acm模式输入输出11道题分析与总结

 
Category: C_C++

写在前面

感觉好久没写博客了, 最近看的书多, 但是真正沉淀下来的东西却很少…

这次总结一下C++刷题中常用的一些IO操作, 也就是ACM模式中的一些基本操作.

看到知识星球里面推荐了牛客的一个比赛, 其中有11道题都是关于C++刷算法题完整程序的输入输出部分, 值得新手学习训练一下, 下面是我的解答, 均通过测试, 可以放心食用.

地址: 牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com);

1: 开胃菜

链接:https://ac.nowcoder.com/acm/contest/5657/A 来源:牛客网

输入包括两个正整数a,b(1 <= a, b <= 1000),输入数据包括多组。 输出描述: 输出a+b的结果

#include <iostream>
using namespace std;
int main(void) {
    int a, b;
    while (cin >> a >> b) { cout << a + b << endl; }
}

2: 读取多个输入

链接:https://ac.nowcoder.com/acm/contest/5657/B 来源:牛客网

输入描述: 输入第一行包括一个数据组数t(1 <= t <= 100) 接下来每行包括两个正整数a,b(1 <= a, b <= 1000) 输出描述: 输出a+b的结果

只比上面的题多了一个输入, 直接读取即可, 甚至不需要这个变量.

#include <iostream>
using namespace std;
int main(void) {
    int a, b, cnt;
    cin >> cnt;
    while (cin >> a >> b) { cout << a + b << endl; }
}

3: 多一个判断

链接:https://ac.nowcoder.com/acm/contest/5657/C 来源:牛客网

输入描述: 输入包括两个正整数a,b(1 <= a, b <= 10^9),输入数据有多组, 如果输入为0 0则结束输入 输出描述: 输出a+b的结果

加上判断为0即可.

#include <iostream>
using namespace std;

int main(void) {
    int a, b;
    while (cin >> a >> b) {
        if (a + b == 0) break;
        cout << a + b << endl;
    }
}

4: 双循环读取

链接:https://ac.nowcoder.com/acm/contest/5657/D 来源:牛客网

输入描述: 输入数据包括多组。 每组数据一行,每行的第一个整数为整数的个数n(1 <= n <= 100), n为0的时候结束输入。 接下来n个正整数,即需要求和的每个正整数。 输出描述: 每组数据输出求和的结果

外层循环遍历行, 内层循环读取列.

#include <iostream>
using namespace std;

int main(void) {
    int a, n, tmp;
    while (true) {
        cin >> n;
        if (n == 0) break;
        tmp = 0;
        while (n--) {
            cin >> a;
            tmp += a;
        }
        cout << tmp << endl;
    }
}

5:同样双循环

链接:https://ac.nowcoder.com/acm/contest/5657/E 来源:牛客网

输入描述: 输入的第一行包括一个正整数t(1 <= t <= 100), 表示数据组数。 接下来t行, 每行一组数据。 每行的第一个整数为整数的个数n(1 <= n <= 100)。 接下来n个正整数, 即需要求和的每个正整数。 输出描述: 每组数据输出求和的结果

同样双循环, 有了外层读取到的行数, 直接作为循环变量即可.

#include <iostream>
using namespace std;
int main(void) {
    int a, n, tmp, nn;
    cin >> n;
    while (n--) {
        tmp = 0;
        cin >> nn;
        while (nn--) {
            cin >> a;
            tmp += a;
        }
        cout << tmp << endl;
    }
}

6: 双循环

链接:https://ac.nowcoder.com/acm/contest/5657/F 来源:牛客网

输入描述: 输入数据有多组, 每行表示一组输入数据。 每行的第一个整数为整数的个数n(1 <= n <= 100)。 接下来n个正整数, 即需要求和的每个正整数。 输出描述: 每组数据输出求和的结果

有一点小小的区别, 注意读取第一个数之后进入内层循环.

#include <iostream>
using namespace std;
int main(void) {
    int a, tmp{}, n;
    while (cin >> n) {
        tmp = 0;
        while (n--) {
            cin >> a;
            tmp += a;
        }
        cout << tmp << endl;
    }
}

7: 双循环读取边界

链接:https://ac.nowcoder.com/acm/contest/5657/G 来源:牛客网

输入描述: 输入数据有多组, 每行表示一组输入数据。

每行不定有n个整数,空格隔开。(1 <= n <= 100)。 输出描述: 每组数据输出求和的结果

注意边界条件, 没有数据范围之后只能用\n来判断, 当然还有用字符流的方法, 这里就不多说了.

#include <iostream>
using namespace std;

int main(void) {
    int a, tmp{};
    while (cin >> a) {
        tmp += a;
        if (cin.get() == '\n') {
            cout << tmp << endl;
            tmp = 0;
        }
    }
}

8: 字符数组操作

从这个题开始, 就到了字符数组部分了, 需要注意读取的时候的边界条件, 以及排序.

链接:https://ac.nowcoder.com/acm/contest/5657/H 来源:牛客网

输入描述: 输入有两行,第一行n

第二行是n个字符串,字符串之间用空格隔开 输出描述: 输出一行排序后的字符串,空格隔开,无结尾空格

说的是没有结尾空格, 为了方便写我直接range-based-for, 但是也过了.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main(void) {
    int n;
    string s;
    cin >> n;
    vector<string> ans(n);
    while (n--) {
        cin >> s;
        ans[n] = s;
    }
    sort(ans.begin(), ans.end());
    for (auto it : ans) cout << it << " ";
}

9: 字符数组

链接:https://ac.nowcoder.com/acm/contest/5657/I 来源:牛客网

输入描述: 多个测试用例,每个测试用例一行。

每行通过空格隔开,有n个字符,n<100 输出描述: 对于每组测试用例,输出一行排序过的字符串,每个字符串通过空格隔开

这个题和上面的很像, 只不过需要自己考虑输入边界, 也就是\n情况.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main(void) {
    string s;
    vector<string> ans{};
    while (cin >> s) {
        ans.emplace_back(s);
        if (cin.get() == '\n') {
            sort(ans.begin(), ans.end());
            for (auto it : ans) cout << it << " ";
            cout << endl;
            ans.clear();
        }
    }
}

10: 综合题

链接:https://ac.nowcoder.com/acm/contest/5657/J 来源:牛客网

输入描述: 多个测试用例,每个测试用例一行。 每行通过,隔开,有n个字符,n<100 输出描述: 对于每组用例输出一行排序后的字符串,用’,’隔开,无结尾空格

比较复杂, 但是也可以接受, 用到了一个string的substr方法, 虽然资源占用大, 但是数据量小并不影响.

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;

int main() {
    string s;
    vector<string> ans{};
    while (cin >> s) {
        int j = 0;
        for (int i{}; i < s.size(); ++i)
            if (s[i] == ',') ans.emplace_back(s.substr(j, i - j)), j = i + 1;
        ans.emplace_back(s.substr(j, s.size() - j));

        if (cin.get() == '\n') {
            sort(ans.begin(), ans.end());
            int n = ans.size();
            for (int i{}; i < n; ++i)
                cout << ans[i] << ((i == n - 1) ? "\n" : ",");
            ans.clear();
        }
    }
}

参考别人的sstream写法(简洁明了):

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <sstream>

using namespace std;

int main() {
    string s;
    while (getline(cin, s)) {
        vector<string> ves;
        string item;
        stringstream ss(s);
        while (getline(ss, item, ',')) ves.push_back(item);
        sort(ves.begin(), ves.end());
        for (int i{}; i < ves.size(); i++) {
            cout << ves[i];
            if (i != ves.size() - 1) cout << ',';
        }
        cout << endl;
    }
}

11: 细节题

链接:https://ac.nowcoder.com/acm/contest/5657/K 来源:牛客网

数据范围: $0<a,b<2\times10^{10}$.

输入描述: 输入有多组测试用例,每组空格隔开两个整数 输出描述: 对于每组数据输出一行两个整数的和

最后的开胃菜, 注意数据范围即可.

#include <iostream>
using namespace std;
int main(void) {
    long long a, b;
    while (cin >> a >> b) { cout << a + b << endl; }
}