在比赛中一般都是要求标准输入读数据,还有执行时长限制,一般都是读入数字,
一、典型的输入有几种写法:
1) 禁用缓冲区同步
//#include<bits/stdc++.h>
#include <iostream> // cin cout
#include <cstdio> // ios
//#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdint.h>
using namespace std;
ios::sync_with_stdio(false);
cout.sync_with_stdio(false);
cin.tie(0);
2) 使用getchar,自己做数字转换
#define nc() (char)getc(stdin)
inline int readInt32()
{
static char c = nc();
if (c == EOF)
{
return INT32_MAX;
}
int x = 0, f = 1;
// 先需要跳过空格等其他符号,并查找负号
for (; c > '9' || c < '0'; c = nc())
{
if (c == '-')
f = -1;
}
// 读取数字,遇到空格等其他字符结束
for (; c <= '9'&&c >= '0'; c = nc())
{
x = (x << 3) + (x << 1) + c - 48;
}
return x * f;
}
3)见到有人说使用fread优化读入,
但是,我觉得是不行的,读文件可以,stdin不行,因为数据不够的时候不返回
inline char nc()
{
static char buf[100000];
static char *p1 = buf; // 指向头位置,向后滑动
static char *p2 = buf; // 读完指向尾部,
// 如果相同,则说明没有数据了,需要复位重读一次;
if (p1 == p2)
{
p1 = buf;
p2 = p1 + fread(buf, 1, 100000, stdin);
}
return (p1 == p2) ? EOF : *p1++;
}
这段代码无论是linux还是windows都会卡到fread那里,反正我是不会改;
4) fgets优化,
我觉得fgets相对简单,一次读一行,遇到\n是结束,其实getchar也是遇到换行才开始返回的;
inline char nc()
{
static char buf[4096];
static char *p = buf;
if (*p == '\0')
{
// fgets函数得到的字符串是带有回车符的'\n'
fgets(buf, 1023, stdin);
p = buf;
}
return (*p == '\0') ? EOF : *p++;
}
输出有很多优化方法:
我这里给一个手写的fwrite优化,减少调用次数:
static char output[100000];
static char * p = output;
// 这里全局变量设置的比较大,考试测试数据可能一般是10万量级
inline void flushout()
{
*p = '\0';
fwrite((char *)output, 1, p - (char *)output, stdout);
p = output;
}
inline int print(int n)
{
static char * pEnd = output + 100000;
// flush
int len = pEnd - p;
if ( len < 20)
{
flushout();
}
// 这里根据要求,在缓冲区自己格式化,
int ret = snprintf(p, len, "%d\n", n);
p += ret;
return ret;
}
一个使用示例是:
int main()
{
/*ios::sync_with_stdio(false);
cout.sync_with_stdio(false);
cin.tie(0);*/
printf("请输入一行数据:\n");
int t;
for (int i =0; i<10; i++)
{
t = readInt32();
print(t);
}
flushout();
return 0;
}