우선 fastIO란 무엇인가?
IO 버퍼크기는 2048바이트 정도로 버퍼에서 한번에 나눠서 받기 때문에 이 값 이상의 버퍼 값이 들어온다면 비효율적으로
들어올 수 있다
따라서 우리는 이런 상황에 fastIO를 사용할 수 있다
fastIO는 값을 받을 때 한번에 받아서 해당 값을 처리해준다
코드는 아래와 같다(picuhila님의 코드를 참고하였다)
unroll-roops는 최적화에 쓰이는 방법인데, 현재에서 다루는 과정은 아니기 때문에 생략한다
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class FastIn
{
public:
const static int BUFFER_MAX = 1048575;
static char buf[BUFFER_MAX + 1];
static int pos;
FastIn()
{
clear();
}
static void clear()
{
pos = BUFFER_MAX;
}
static void read_buffer()
{
fread(buf, sizeof(char), BUFFER_MAX, stdin);
}
static char getchar()
{
if (pos == BUFFER_MAX)
{
read_buffer();
pos = 0;
}
return buf[pos++];
}
static int nextint()
{
int res = 0;
char c;
do
{
c = getchar();
} while (c < '0' || c>'9');
res = c - '0';
while (1)
{
c = getchar();
if (c < '0' || c>'9')break;
res = (res * 10) + c - '0';
}
return res;
}
};
char FastIn::buf[FastIn::BUFFER_MAX + 1];
int FastIn::pos;
int v[3000009];
int ch[3000009];
int l, ml, mk, c,x;
int main()
{
l = FastIn::nextint(); //총 거리
ml = FastIn::nextint(); //기관총 유효 사거리
mk = FastIn::nextint(); //기관총 데미지
c = FastIn::nextint(); // 거리1에 한해 무한대 데미지를 주는 수류탄 개수
for (int i = 0; i < l; i++)
{
v[i] = FastIn::nextint(); //0m부터 총거리까지 좀비체력
}
int dam = mk;
for (int i = 0; i < l; i++)
{
if (ch[i]) dam -= mk;
if (v[i] -dam > 0)
{
c--;
if (c < 0)
{
cout << "NO";
return 0;
}
}
else
{
if (i + ml < l)
{
ch[i + ml] = 1;
}
dam += mk;
}
}
cout << "YES";
return 0;
}
우선 fread의 코드는 아래와 같다
fread로 우리는 static으로 이미 값을 받고 해당 값을 char 배열에 넣고 시작한다
그 다음 null이라는 중간 공백으로 구분을 한다
fastio를 쓰는 예시는 아래와 같다
https://www.acmicpc.net/problem/19644
이제 여기서 나는 io값은 최대 얼마인가?
처음에는 7글자이다(3*10^6은 6글자로 표현가능 + 공백 한글자)
그 다음에는 7+(3*10^6)*4이다 (기관총 범위 3*(10^6)만큼 입력하고(총 6글자+공백 한글자), 해당 입력범위에서 각각의 거리에 대한 데미지가 최대 100까지 설정하므로 (각각 3글자+공백한글자)
그 다음에는 7글자 (3*10^6) 만큼 입력된다
그러면 왜 100만에 가까운 수부터 1mb까지가 효과적이었는가?
간단하다 입력이 최악인 경우 10^6이 아니라 10^6에 가까운 값만큼 L에 입력되었기 때문이다 그래서 1mb에 못미치는 값이 입력되었기 때문에 입력받을 떄 크기가 1mb보다 약간 작아도 잘 작동했다
이제 생기는 의문은 왜 1MB보다 큰 값에서는 오히려 시간이 오래걸리냐인데, 여기서 백준에서는 반도체 관련 기술자분들이라고 해서 이게 뭔 말이지 싶었는데
https://ljhblog.tistory.com/59
메모리 연산은 리얼모드에서 최대 1MB로 8086프로세서와 교환 가능하다
여기서 8086 프로세서가 무엇이냐하면
간단히 말하면 어셈 배울 때 Thumb Instruction이라고 해서 우리가 잘아는 명령어인 EQ(동일), GE(크거나 같다),LE(작거나 같다) 등 이거 관련 명령어를 가지고 있는 친구가(스프링 타임리프쪽에서 아마 본 적이 있을 것 같다)
https://namu.wiki/w/%EC%9D%B8%ED%85%94%208086?from=8086
8086프로세서(16비트 컴퓨터)이후에도 계속 새로운 프로세서(32비트 컴퓨터,64비트 컴퓨터)가 나왔는데
위에서 최대의 메모리를 다룰 수 있는 1MB 처리를 다루는 리얼모드는 동일한 것 같다
따라서 1MB연산이 가장 최적화되어있는 상태라고 말 할 수 있다.
아래 쪽에 관심있으면 플래그 레지스터(flag register)라고 해서 어셈에서 다루는 거라고 하니까 찾아보면 좋을 것같다