写在前面
感觉好久没写博客了, 最近看的书多, 但是真正沉淀下来的东西却很少…
这次总结一下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; }
}