多组输入输出问题
和上一篇博客有一点点重复
1001 : A+B for Input-Output Practice (I)
题目链接
Description
计算A+B 程序设计任务中常常会包含多组输入输出。
Input
第一行一个正整数n,代表输入数据的组数。 以下n行,每行两个正整数
Output
计算这n组数的和,每组答案占一行
Sample Input
2 1 5 10 20
Sample Output
6 30
需要注意的问题
这道题是oj中第二道题,可能也是很多同学第一次遇到多组输入的问题。 ①一般情况下,我们是通过定义一个变量来记录需要输入的组数,每输入一组,就对变量进行-1的操作,直至计数变量减为0。(具体细节见代码) ②不知道大家开始有没有相同的想法,很多人刚开始看见这种问题的时候会想开一个数组把所有的结果存储下来,最后一起输出,以达到和样例里相同的输出打印效果。但是,根本没有这个必要,只需读一组数据立即就输出一组数据的结果即可。
C++
#include<iostream>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int a,b;
cin>>a>>b;
cout<<a+b<<endl;
}
return 0;
}
C
#include<stdio.h>
int main()
{
int t,a,b;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&a,&b);
printf("%d\n",a+b);
}
return 0;
}
无限组输入输出问题
1002 : A+B for Input-Output Practice (II)
题目链接
Description
计算A+B
程序设计任务中往往包含多组数据。
但有时并不会告诉你要输入的组数。
Input
输入包括多组数据,
每组数据占一行,包括两个正整数。
Output
对于输入的每一组数据,输出他们的和,每组输出占一行。
Sample Input
1 5 10 20
Sample Output
6 30
实现方法
方法1(适用于C、C++)
#include<stdio.h>
int main()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF)
{
printf("%d\n",a+b);
}
return 0;
}
关于 scanf("%d%d",&a,&b)!=EOF 的结果
- 如果a和b都被成功读入,那么上面表达式的结果为2。
- 如果只有一个读入,那么上面表达式的结果为1。
- 如果a&&b都没有读入,那么上面表达式的结果为0(若a没有读入,则直接放弃b的读入)。
- 如果遇到错误或者文件结尾,那么上面表达式的结果为EOF,对应的有符号数时-1。
- 如果遇到Crrl+Z,那么上面表达式的结果为EOF,对应的有符号数时-1。
方法2(适用于C、C++)
#include<stdio.h>
int main()
{
int a,b;
while(~scanf("%d%d",&a,&b))
{
printf("%d\n",a+b);
}
return 0;
}
~的作用是“按位取反”。 scanf函数返回值为int型。如果a和b都被成功读入,那么scanf的返回值就是2,如果只有a被成功读入,返回值为1。 如果没有输入值就是返回-1,-1按位取反结果是0。
方法3(仅适用于C++)
#include<iostream>
using namespace std;
int main()
{
int a,b;
while(cin>>a>>b)
{
cout<<a+b<<endl;
}
return 0;
}
有输入结束标志的输入问题
1003 : A+B for Input-Output Practice (III)
题目链接
Description
计算A+B。 程序设计任务中往往包含多组数据。 以0作为输入结束标志。
Input
多组测试数据,每组测试数据占一行,包括2个整数a,b。 如果输入0 0,则表示输入结束。
Output
每组测试数据占一行,输出两个整数的和。
Sample Input
1 5 10 20 0 0
Sample Output
6 30
实现方法
当仅仅是无限组输入时,我们通过上边提到的两种方法来进行输入。有结束条件的输入问题就相当于在上面问题的基础上再加一个限制条件。 对于本题来说,在无限组输入的情况下,再判断一下a、b是否同时为0即可。 下面代码给出一般情况下的解决办法:
#include<iostream>
using namespace std;
int main()
{
int a,b;
while(cin>>a>>b&&(a||b))
{
cout<<a+b<<endl;
}
return 0;
}
字符串的读入问题
1005 : 复读机 for Input-Output Practice (V)
题目链接
Description
所谓复读机,那就是复读,就是复读,就是复读,就是复读…
[本题于2019.10.28修改并重判]
Input
第一行包括一个正整数T,表示输入数据组数。(1 < T < 10)
每一组输入数据为长度不超过20的一句话。
Output
对于每组输入,原样输出输入的内容。
Sample Input
3 Hello World! I love NCST! I love ACM!
Sample Output
Hello World! I love NCST! I love ACM!
读入过程中可能会遇到的问题
①如何读入带有空格的一行字符串? ②为什么有的人的代码只能读入样例中三行字符串中的前两行?
解决办法
① C语言中,可以用gets函数来接收输入的字符串(包含空格)。
#include<stdio.h>
#include<string.h>
int main()
{
char s[100];
gets(s);
printf("%s\n",s);
return 0;
}
C++中可以不必再定义字符数组来存储字符串,而是可以定义字符串类型的变量。但是同样,还是不能通过普通的读入直接读取一整行带有空格的字符串,我们需要借助函数 getline(cin,s) 来读入。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
string s;
getline(cin,s);
cout<<s<<endl;
return 0;
}
② 在解决了整行字符串的输出问题之后,部分同学可能还会遇到一下问题: 写出了一个看似很正确的代码(类似下边这个代码):
#include<stdio.h>
#include<string.h>
int main()
{
int n;
char s[500];
scanf("%d",&n);
while(n--)
{
gets(s);
printf("%s\n",s);
}
return 0;
}
在输入测试样例之后发现输出结果和自己预想的不太一样:
3 Hello World! Hello World! I love NCST! I love NCST!
出现这种情况的原因主要是数字3后边存在换行符,所以在读入数字3之后第一次读入的不是第一行字符串,而是换行符,以至于出现了上述结果。 所以我们应该想办法吞掉换行符,在此给出较为常用的两种方法。
方法1
#include<stdio.h>
#include<string.h>
int main()
{
int n;
char s[500];
scanf("%d\n",&n);
while(n--)
{
gets(s);
printf("%s\n",s);
}
return 0;
}
方法2
#include<stdio.h>
#include<string.h>
int main()
{
int n;
char s[500];
scanf("%d",&n);
getchar();
while(n--)
{
gets(s);
printf("%s\n",s);
}
return 0;
}
快速读入模板(小技巧)
当数据输入规模较大时,比scanf快。
#include<iostream>
#include<cstring>
using namespace std;
inline int read()
{
int x=0,f=0;
char ch=getchar();
while(ch<'0' || ch>'9')
{
if(ch=='-')
f=1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return f?-x:x;
}
int main()
{
int a=read();
cout<<a<<endl;
return 0;
}
|