提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
前言
本系列博客是本人学习程序设计算法课程的一些总结与思考,依托杭电OJ以及PTA中的部分习题,希望在算法学习方面能有更多收获。本文是程序设计竞赛算法中常见的输入输出问题。程序竞赛中题目的输入数据和输出数据有多组且格式多种多样。
一、输入问题
1.输入不说明有多少个Input Block,以EOF为结束标志
C语法:
while(scanf("%d %d", &a, &b) != EOF) {
...
}
//scanf函数的返回值是读出的变量个数:若只有一个整数输入,返回值是1;若一个输入都没有,返回值是-1
//EOF是一个预定义的常量-1
C++语法:
while(cin>>a>>b) {
...
}
2.由用户设定Input Block的数目
例1:计算两数之和
#include <stdio.h>
int mian() {
int n, i, a, b;
scanf("%d", &n); //cin >> n;
for(i = 0; i < n; i++) {
scanf(%d %d", &a, &b);
printf("%d\n", a + b);
}
}
3.输入不说明有多少个Input Block,但以某个特殊输入作为结束表示
例2:假如上例以输入0 0作为结束标志
#include <stdio.h>
int main() {
int a, b;
while(scanf("%d %d", &a, &b) && (a != 0 || b != 0)) //注意不是“(a != 0 && b != 0)”
printf("%d\n", a + b);
}
例3:要求设定每组元素数目,若为0则结束,求出各组元素之和
#include <iostream>
using namespace std;
int main() {
int n, a, sum = 0;
while (cin >> n && n != 0) { //n是各组元素数目
while (n--) {
cin >> a;
sum += a;
}
cout << sum << endl;
sum = 0; //sum在第二次计算之前要清零
}
return 0;
}
例4:要求设定数据组的个数以及每组元素的个数,求出每组元素之和
#include <stdio.h>
int main() {
int u, n, t, sum;
scanf("%d", &u); //设定数据组个数
while(u--) {
scanf("%d", &n); //设定当前组元素个数
sum = 0;
while(n--) {
scanf("%d", &t);
sum += t;
}
printf("%d\n", sum);
}
return 0;
}
4.输入一整行的字符串
C语法:
char buf[20];
gets(buf);
C++语法:
string buf;
getline(cin, buf); //它的函数声明形式为:istream& getline(char line[], int size, char endchar = '\n');
//或者:
char buf[255];
cin.getline(buf, 255);
//cin >> :输入一个数字或字符;接收一个字符串,遇“空格” “TAB” “回车”就结束
//cin.getline :接收一个字符串,可以接收空格并输出 //istream流
//getline() :接收一个字符串,可以接收空格并输出 //#include <string>
//综上:在同时使用cin>>和getline()时,cin>>之后应该将回车符作为输入流cin以清除缓存,否则系统默认把之前的变量作为输入流
cin >>;
str = "\n";
getline(cin, str);
其他输入字符串的方法:
//接收短字符串用scanf函数
scanf("%s %s", str1, str2); //在多个字符串之间用一个或多个空格分隔
//接收长字符串用gets函数
gets(str1);
//getchar每次只接收一个字符
c = getchar();
例5:【HDOJ1048】输入一行字符串,依次输出每个字符向左移动5位得到的字符。输入输出之要求:此问题的输入将包含最多 100 个数据集的(非空)系列。每个数据集将根据以下描述进行格式化,并且数据集之间没有空行分隔。所有字符都将是大写的。单个数据集有 3 个组成部分:起始行是单行“START”, 密码消息是包含一到两百个字符的单行,包括来自用户输入的单行,结束行是单行“END” ,可以输入多个数据集,在最终数据集之后将是一行“ENDOFINPUT”。
#include <iostream>
using namespace std;
#include <string>
int main() {
string s;
while (getline(cin, s) && s.compare("ENDOFINPUT") != 0) {
if (s.compare("START") != 0 && s.compare("END") != 0) {
for (int i = 0; i < s.length(); i++) {
if (s[i] >= 'F' && s[i] <= 'Z') {
s[i] -= 5;
}
else if (s[i] >= 'A' && s[i] <= 'E') {
s[i] += 21;
}
cout << s[i];
}
cout << endl;
}
}
return 0;
}
二、输出问题
1.当输入不说明Input Block的数目,以EOF为结束标志。输出时一个Input Block对应一个Output Block
C语法:
{
....
printf("%d\n", ans); //要求有空行:printf("%d\n\n",ans);
}
C++语法:
{
cout << ans << endl; //要求有空行:cout << ans << endl << endl;
}
2.要求每一个Output Block之间有空行,而最后一个Output Block没有空行
例:计算每组数据元素之和,要求输入组数,每组元素总数,输出各组元素之和,且相邻输出组间用空行隔开,但是最后一组输出没有空行
#include <stdio.h>
int main() {
int t, n, a, i, j, sum;
scanf("%d", &t); //数据块组数
for(i = 0; i < t; i++) {
sum = 0;
scanf("%d", &n); //当前组中元素个数
for(j = 0; j < n; j++) {
scanf("%d", &a);
sum += a;
}
if(i < t -1)
printf("%d\n\n", sum);
else
printf("%d\n", sum);
}
}
总结
本文主要对程序设计竞赛中常见的输入输出问题做一简单概括,在程序设计竞赛中应当注意题目中所要求的输入输出格式,避免不必要的错误。