社区讨论

特别提醒:该题的数据格式有问题!

P4414[COCI 2006/2007 #2] ABC参与者 3已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@mk280d99
此快照首次捕获于
2026/01/06 14:40
2 个月前
此快照最后确认于
2026/01/09 20:15
2 个月前
查看原帖

省流

讨论区已经看到有很多人被这题的数据坑了
这道题的数据的换行符格式为\r\n,在linux下不会自动转换,导致换行符被视为两个字符,需要用户自行处理
如果使用
C
scanf("%d%d%d",...);
getchar();
scanf("%c%c%c",...);
或者
C
scanf("%d%d%d",...);
getchar();
gets(s);
// 或 cin.getline(s);
// 或 getline(cin, s);
它们均无法正确读取,这样写会导致少读一个字符,从而答案错误
最简单解决办法是用cin,如果你会c++的话。因为cin自动忽略空白符,包括\r
或者使用两个getchar:
C
scanf("%d%d%d",...);
getchar();
getchar();
scanf("%c%c%c",...);
或者在格式串中用空格匹配空字符,\r也会被认为是空字符:
C
scanf("%d%d%d",...);
// 或 scanf("%d%d%d\n",...);
// 或 scanf("%d%d%d ",...);
// 如果这么写,你必须清楚你在干什么

scanf(" %c%c%c",...);

原理

众所周知windows和linux下的换行符格式不同:
  • windows下是\r\n(CRLF,回车换行),两个字符
  • linux下是\n(LF,换行),一个字符
\r是回车,ascii码为13,表示回到当前行的开始
\n是换行,ascii码为10
通常来说,如果使用c语言标准库函数读或写文本文件(例如fopen("r")),或者将输入流stdin重定向到文件(通常oj都是使用重定向的方法评测),c语言都会自动处理这种差异,也就是在windows下会自动把\r\n转换为\n,从而实现了跨平台
但是,如果你将一个windows下的文本文件复制到了一个linux操作系统上,c库函数检测到当前平台是linux,则不会自动处理这种差异,此时\r\n视为两个字符,需要用户自行处理
同理,如果你用windows打开linux格式的文本文件,有时就会发现所有文本都挤在了同一行中,也是一样的原理

如何发现和验证的

我们拿不到洛谷的数据,但是可以看到一些有用的信息
首先,用两个getchar,或在格式串中用空格匹配空字符,都可以通过该题:
C
scanf("%d%d%d",...);
getchar();
getchar();
scanf("%c%c%c",...);
或:
C
scanf("%d%d%d ",...);
// 或 scanf("%d%d%d\n",...);
// 如果这么写,你必须清楚你在干什么

scanf("%c%c%c",...);
// 或 scanf(" %c%c%c",...);
但是这并不能说明是回车符\r引起的问题,也可能是行末多了一个空格(我也遇到过这样的奇葩数据)
提交如下的测试程序:
C
#include <stdio.h>
int main() {
  int a,b,c;
  scanf("%d%d%d",&a,&b,&c);
  char ch = getchar();
  if (ch == 13)
    printf("%d", 1);
  return 0;
}
查看提交结果的测试点信息,内容如下:
PLAINTEXT
Wrong Answer.wrong answer On line 1 column 1, read 1, expected ....
说明读取到的字符是ascii码为13的字符,也就是回车符\r,而非换行符
如果社区注意到了这个问题,请核实一下,有必要的话可修复数据

回复

7 条回复,欢迎继续交流。

正在加载回复...