0%

ACM模式下C语言和Python的测试用例输入方式整理

在OJ网站上做题时经常出现一种情况,那就是题会做,但是不知道多组输入如何处理,导致无法AC。
本文对ACM模式下C语言和Python的测试用例的输入方式进行了系统的整理。

ACM模式VS核心代码模式

有些企业是在牛客上进行面试,有些企业是在力扣上进行面试,两个平台答题模式是有区别的,所以搞懂不同的输入代码模式是很重要的。

ACM输入模式:在这种模式下,你需要自己构造输入数据格式,把要需要处理的容器填充好,OJ不会给你任何代码,你需要自己导入所需的库,定义数据结构,读取和解析输入数据,然后根据题目要求输出结果,最后也要自己根据题目提示控制返回数据的格式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <vector>
using namespace std;

int main() {
int n;
cin >> n;
vector<int> nums(n);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
// 算法逻辑...
return 0;
}

LeetCode 的核心代码模式:在这种模式下,LeetCode 已经为你处理了输入数据,将其封装在了特定的数据结构中(如数组、链表、二叉树等)。你只需要关注如何实现题目要求的算法逻辑,不需要处理输入和输出。这种模式下,你可以更专注于算法本身,但对于数据结构和输入输出的处理则有所限制。

1
2
3
4
5
6
class Solution {
public:
int someFunction(vector<int>& nums) {
// 算法逻辑...
}
};

可以看出ACM模式要比核心代码模式多写不少代码,相对来说ACM模式更锻炼代码能力,而核心代码模式是把侧重点完全放在算法逻辑上。

OJ系统中C语言各种输入方式

ACM模式要求写出来的代码是直接可以本地运行的,所以我们需要自己写include哪些库函数,构造输入用例,构造输出用例,因此在OJ网站上做题时经常出现一种情况,那就是题会做,但是不知道多组输入如何处理,导致无法AC。

输入一个数,并原样输出,测试数据有多组:

1
2
3
4
while(scanf(“%d”,&a)!=EOF)
{
printf(“%d\n”,a);
}

先输入一个n,后输入一个共n个数的数组,输出这个数组:

1
2
3
4
5
scanf(“%d”,&n);
for(i=0;i<n;i++)
{
scanf(“%d”,&a[i]);
}

先输入一个n后输入一个共n个数的数组,最后在跟一个数X,在这n个数中查找x:

1
2
3
4
5
6
scanf(“%d”,&n);
for(i=0;i<n;i++)
{
scanf(“%d”,&a[i]);
}
scanf(“%d”,&x);

输入一组数,以0为结束标志:

1
while(scanf(“%d”,&n),n!=0)

示例1:输入一个数x再原样输出,测试数据有多组,以0为结束标志:

1
2
3
4
5
6
7
8
9
#include<stdio.h>
int main()
{
int x;
while(scanf("%d",&x),x!=0)
{
printf("%d\n",x);
}
}

示例2:输入一个数组并原样输出,先输入一个n代表数组有n个数,测试数据有多组,以输入的n=0时为结束标志:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<stdio.h>
int main()
{
int n,a[10],i;
while(scanf("%d",&n),n!=0)
{
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
}

二维数组的输入方式:第一行输入一个n,代表接下来输入一个n*n的二维矩阵:

1
2
3
4
scanf(“%d”,&n);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf(“%d”,&a[i][j]);

示例:输入一个二维数组并原样输出,测试数据有多组:

注意:每输入一组数据,按一次回车并输出一组的结果,然后再输入下一组测试数据再按回车再输出下一组的结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<stdio.h> 
int main()
{
int n,i,j,a[10][10];
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&a[i][j]);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d",a[i][j]);
if(j!=n-1)
printf(" ");
}
printf("\n");
}
}
}

末尾加char()

1
2
3
4
while(scanf(“%c”,&c)!=EOF)             
{
末尾加getchar(); //按了回车也算是输入了一个字符
}

示例:输入一个字符,并判断字符串类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h> 
int main()
{
char c;
while(scanf("%c",&c)!=EOF)
{
if(c>='a'&&c<='z'||c>='A'&&c<='Z')
printf("alpha\n");
else if(c>='0'&&c<='9')
printf("numeric\n");
else printf("other\n");
getchar();
}
}

字符串中不带空格

1
2
3
4
while(scanf(“%s”,&str)!=EOF) 
{

}

示例:判断不含空格的字符串是由为回文串:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<stdio.h> 
#include<string.h>
int main()
{
char s[100];
int x,u,i;
while(scanf("%s",s)!=EOF)
{
x=strlen(s);
for(i=0;i<x;i++)
{
if(s[i]!=s[x-1-i])
{
u=0;break;
}
if(s[i]==s[x-1-i])
{
u=1;
}
}
if(u==1)
printf("Yes\n");
else if(u==0)
printf("No\n");
}
}

输入不含空格的字符串数组

1
2
for(i=0;i<n;i++) 
scanf("%s",s[i]);

示例:输入一个n,后面跟n个无空格字符串,(相邻字符串要用空格隔开),输出字符串长度,测试数据有多组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<string.h> 
#include<stdio.h>
int main()
{
int n,i,j;
while(scanf("%d",&n)!=EOF)
{
int a[20]={0};
char s[20][60];
for(i=0;i<n;i++)
scanf("%s",s[i]);
for(i=0;i<n;i++)
{
a[i]=strlen(s[i]);
}
for(i=0;i<n;i++)
{
printf("%s",s[i]);printf("%d\n",a[i]);
}
}
}

带空格的字符串

1
2
3
4
while(gets(str)!=NULL)    
{

}

示例:判断多组含空格的字符串是否为回文串:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<stdio.h> 
#include<string.h>
int main()
{
char s[100];
int x,u,i;
while(gets(s)!=NULL)
{
x=strlen(s);
for(i=0;i<x;i++)
{
if(s[i]!=s[x-1-i])
{
u=0;break;
}
if(s[i]==s[x-1-i])
{
u=1;
}
}
if(u==1)
printf("Yes\n");
else if(u==0)
printf("No\n");
}
}

输入字符串数组(含空格)

1
2
for(i=0;i<n:i++)
gets(s[i]);

示例:计算几行字符串的长度,第一行输入n,下面n行每一行输入一个含空格的字符串:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<string.h> 
#include<stdio.h>
int main()
{
int n,i,j;
char s[20][60];
while(scanf("%d",&n)!=EOF)
{
int a[20]={0};
for(i=0;i<n;i++)
gets(s[i]);
for(i=0;i<n;i++)
{
a[i]=strlen(s[i]);
}
for(i=0;i<n;i++)
{
printf("%d\n",a[i]);
}
}
}

测试数据有T组,先输入一个组数T,接下来每一行第一个数为每组数的个数n,n的后面再跟n个数:

1
2
3
4
5
6
7
scanf(“%d\n”,&T);                                
while(T--) //当T减到0跳出循环
{
scanf(“%d”,&n);
for(i=0;i<n;i++)
scanf(“%d”,&a[i]);
}

示例:输入一个一维数组,并原样输出,先输入一个T,代表有T组测试数据,下面T行每行第一个数n代表每个数组的元素个数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<stdio.h> 
int main()
{
int n,i,a[10],T;
scanf(“%d”,&T);
while(T--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
}

OJ系统中Python的多行输入

input()与sys.stdin概述

在线判题系统(Online Judge)的多行输入问题分为定行输入与不定行输入。

若为定行输入,使用循环+input()即可解决。
若为不定行输入,还要看是否有输入结束的标志。

若不定行输入带结束标志,最简单的方法,使用while循环加结束判断语句即可。
若不定行输入不带结束标志,我们应当使用系统输入sys.stdin较为方便,也可使用其他方法。

这里要注意一点,不定行输入不带结束标志问题,在本地IDE上测试时,输入是自己定义的,输入结束你可以疯狂按回车键,如果你通过判断输入是否为空作为跳出循环的判断语句,你的代码可能可以运行正确,但是在OJ里这种判断方法是错误的,是不可取的。

不定行输入有结束标志示例

题目描述 计算a+b

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

输出描述: 输出a+b的结果

示例:
输入
1 5
10 20
0 0

输出
6
30

方法1:sys.stdin

1
2
3
4
5
import sys
for line in sys.stdin:
x,y = map(int, line.split())
if x or y:
print(x+y)

方法2:while+input()

注意:使用while循环时,必须加循环结束语句以保证一定能跳出循环,否则OJ不通过。

1
2
3
4
5
while True:
x,y = map(int, input().split())
if x == 0 and y == 0:
break
print(x+y)

不定行输入无结束标志示例

题目描述 计算a+b

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

输出描述: 输出a+b的结果

示例:
输入
1 5
10 20
0 0

输出
6
30

方法1:sys.stdin

1
2
3
4
import sys
for line in sys.stdin:
a,b = map(int, line.split())
print(a+b)

方法2:while+input()

多行输入没有结束标志时,若使用while循环,我们应当使用try,except语句。如下:

1
2
3
4
5
6
while True:
try:
a,b = map(int,input().split())
print(a+b)
except:
break

通过判断输入是否为空作为跳出循环的判断语句,是错误的,如下:

1
2
3
4
5
6
7
while True:
line = input()
if line == '':
break
else:
a,b = map(int,line.split())
print(a+b)

代码样例

输入为int

  1. 输入包括两个正整数a和b,输入数据包含多组。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import sys
    line = sys.stdin.readlines()

    for line in lines:
    numlist = list(map(int, line.split()))
    print(sum(numlist))
    ```

    2. 输入第一行包括一个数据组数t,接下来每行包括两个正整数a,b,求a+b的结果。
    ```python
    import sys
    lines = sys.stdin.readlines()
    n = int(lines[0])
    for i in range(n):
    numList = list(map(int, lines[i+1].split()))
    print(sum(numList))
  2. 输入包括两个正整数a,b,输入数据有多组,如果输入为0,则结束输入。

    1
    2
    3
    4
    5
    6
    while True:
    a,b = map(int,input().split())
    if a== 0 and b == 0:
    break
    else:
    print(a+b)
  3. 计算一系列数的和,输入包括多组数据。每组数据一行,每行的第一个整数为整数的个数n,n为0得时候结束输入。接下来的n个正整数,即需要求和的每个正整数。

    1
    2
    3
    4
    5
    while True:
    a = [int(each) for each in input().split()]
    if a[0]==0:
    break
    print(sum(a[1:]))
  4. 计算一系列数的和,输入的第一行包括一个正整数t,表示数据组数。接下来的t行,每行一组数据。每行的第一个整数为整数的个数n,接下来的n个正整数,即需要求和的每个正整数。

    1
    2
    3
    4
    n = int(input())
    for _ in range(n):
    numList = list(map(int, input().split()))
    print(sum(numList[1:]))
  5. 计算一系列数的和,输入数据有多组,每行表示一组输入数据。每行的第一个整数为整数的个数n。接下来的n个正整数,即需要求和的每个正整数。

    1
    2
    3
    4
    5
    import sys
    lines = sys.stdin.readlines()
    for line in lines:
    numList = list(map(int, line.split()))
    print(sum(numList[1:]))
  6. 计算一系列数的和,输入数据有多组,每行表示一组输入数据。每行不定有n个整数,空格隔开。

    1
    2
    3
    4
    5
    6
    7
    import sys
    for line in sys.stdin:
    a = line.split()
    ret = 0
    for i in range(len(a)):
    ret += int(a[i])
    print(ret)

输入为字符串

  1. 对输入的字符串进行排序后输出。

    1
    2
    3
    4
    5
    6
    7
    8
    while True:
    try:
    n = input()
    strList = list(map(str, input().split()))
    strList.sort()
    print(' '.joint(strList))
    except:
    break
  2. 对输入的字符串进行排序后输出。多个测试用例,每个测试用例一行。每行用空格隔开,有n个字符。

    1
    2
    3
    4
    5
    6
    7
    while True:
    try:
    arr = list(map(str, input().split()))
    arr.sort()
    print(' '.join(arr))
    except:
    break
  3. 对输入的字符串进行排序后输出。多个测试用例,每个测试用例一行。每行通过,隔开,有n个字符。

    1
    2
    3
    4
    5
    6
    7
    while True:
    try:
    a = input().split(",")
    a.sort()
    print(",".join(a))
    except:
    break

其他问题

  1. 输入一个字符串,拆分成单个字符的列表。

    1
    2
    3
    4
    import sys
    str_input = sys.stdin.readline().split()
    strList = [i for i in str_input[0]]
    print(strList)
  2. 第一行表示接下来要输入几组数据

    1
    2
    3
    4
    count = list(map(int, input().split()))
    queue = []
    for _ in range(count[0]):
    queue.append(list(map(int, input().split())))