마음만은 새내기

항상 초심을 잃지 않고 생활하겠습니다~!

프로그래밍/Baekjoon Online Judge

BOJ 11921번(0.1) 문제 풀이

동동매니저 2019. 2. 5. 13:03

[문제 링크]

 

11921번: 0.1

첫째 줄에 수의 개수 N = 5,000,000 이 주어진다. 둘째 줄부터 N개의 줄에는 자연수가 한 줄에 하나씩 주어진다. 입력으로 주어지는 자연수는 10,000,000보다 작거나 같은 자연수이다.

www.acmicpc.net


[문제 분석]

더 빠른 입력 함수를 고민해보는 문제


[풀이]

여기에서 scanf를 사용한다면, 시간 초과를 받을 수 있습니다.

또한, 시간 초과가 아니더라도, 100점 만점을 못받겠죠...

그래서!! 더 빠른 방식을 알려드리고자 합니다.

(필자도 종종 사용하는 방법!!)

바로!! BOJ Blog에도 나와있듯이, fread를 사용하는 방법입니다.

[fread 함수 원형 및 사용법]

fread(void *buffer, size_t elementSize, size_t elementCount, FILE *stream);

buffer : 읽은 데이터를 저장할 버퍼

elementSize : 요소 1개의 크기

elementCount : 읽을 요소의 개수

stream : 읽을 스트림

(원래 fread 함수는 바이너리를 읽을 때 주로 사용이 된다고 합니다.)

여기에서 buffer의 크기를 적당히 잡고,

요소 1개당 1바이트씩, buffer의 크기만큼 읽어들입니다.

그리고 stream은 stdin(표준 입력)으로 지정합니다.

여기에서 주의하실 점은, 데이터가 문자열(바이너리)로 저장된다는 것입니다.

즉, 'a'를 읽었다면, 'a'의 ASCII 코드가 저장되는 것이죠. (숫자도 마찬가지!!)

따라서 숫자를 읽었을 때, ASCII 문자열에서 직접 변환을 해주어야 합니다. (음수가 포함된다면 더 복잡해지죠 ㅠ.ㅠ)

(여기에서는 자연수만 인식이 됩니다. 자세한 구현 방법은 소스 참고!)

마지막으로, 함수에 inline 키워드를 붙이면, 성능이 약간 빨라질 수도 있다고 합니다.

(단, 컴파일러에 따라 무시될 수 있으니 주의!!)


[소스 코드 (C++98)]

#include <cstdio>
using namespace std;

char in[50000000];
int main(void){
	int N=0,i;
	long long sum=0;
	fread(in,1,sizeof(in),stdin);
	for(i=0;in[i]!='\n';i++) N=N*10+in[i]-'0';
	for(int j=0;j<N;j++){
		int tmp=0;
		for(i++;in[i]!='\n';i++) tmp=tmp*10+in[i]-'0';
		sum+=tmp;
	}
	printf("%d\n%lld\n",N,sum);
	return 0;
}

만약 틀린 부분이 있다면 지적 부탁드릴게요~! (댓글 환영!!)