사용법은 이처럼 if문이 나오면 반드시 endif가 나와야 하며 ENABLE이 참(=1)이라면 cout << "ENABLE" << "\n"; 의 코드를 삽입하고 IMPOSSIBLE이 참이라면 cout << "IMPOSSIBLE" << "\n";의 코드를 삽입하라는 뜻이다.
◎ #ifdef 및 #ifndef 지시문
정의 된 연산자와 함께 사용될 때 #if 지시어와 동일한 효과를 가진다.
#ifndef 식별자
#ifndef 식별자
이 지시문은 아래의 지시문과 같은 내용이다.
#if 정의된 식별자
#if! 정의된 식별자
#if는 매크로가 참인지 거짓인지에 따라서 동작한다면 #ifdef는 매크로가 '정의되어 있는지 아닌지'를 기준으로 동작한다.
#ifdef는 매크로가 정의되어 있다면이고
#ifndef는 매크로가 정의되어 있지 않다면이라는 의미이다.
◎ #error 지시문
전처리기가 해당 지시문을 발견하면 컴파일이 중지되고 여기에 포함된 오류 메시지가 전달된다.
수평 직선에 탑 N대를 세웠습니다. 모든 탑의 꼭대기에는 신호를 송/수신하는 장치를 설치했습니다. 발사한 신호는 신호를 보낸 탑보다 높은 탑에서만 수신합니다. 또한, 한 번 수신된 신호는 다른 탑으로 송신되지 않습니다.
예를 들어 높이가 6, 9, 5, 7, 4인 다섯 탑이 왼쪽으로 동시에 레이저 신호를 발사합니다. 그러면, 탑은 다음과 같이 신호를 주고받습니다. 높이가 4인 다섯 번째 탑에서 발사한 신호는 높이가 7인 네 번째 탑이 수신하고, 높이가 7인 네 번째 탑의 신호는 높이가 9인 두 번째 탑이, 높이가 5인 세 번째 탑의 신호도 높이가 9인 두 번째 탑이 수신합니다. 높이가 9인 두 번째 탑과 높이가 6인 첫 번째 탑이 보낸 레이저 신호는 어떤 탑에서도 수신할 수 없습니다.
송신 탑(높이)수신 탑(높이)
5(4)
4(7)
4(7)
2(9)
3(5)
2(9)
2(9)
-
1(6)
-
맨 왼쪽부터 순서대로 탑의 높이를 담은 배열 heights가 매개변수로 주어질 때 각 탑이 쏜 신호를 어느 탑에서 받았는지 기록한 배열을 return 하도록 solution 함수를 작성해주세요.
제한 사항
heights는 길이 2 이상 100 이하인 정수 배열입니다.
모든 탑의 높이는 1 이상 100 이하입니다.
신호를 수신하는 탑이 없으면 0으로 표시합니다.
입출력 예
[6,9,5,7,4]
[0,0,2,2,4]
[3,9,9,3,5,7,2]
[0,0,0,3,3,3,6]
[1,5,3,6,7,6,5]
[0,0,2,0,0,5,6]
입출력 예 설명
입출력 예 #1 앞서 설명한 예와 같습니다.
입출력 예 #2
[1,2,3] 번째 탑이 쏜 신호는 아무도 수신하지 않습니다. [4,5,6] 번째 탑이 쏜 신호는 3번째 탑이 수신합니다. [7] 번째 탑이 쏜 신호는 6번째 탑이 수신합니다.
입출력 예 #3
[1,2,4,5] 번째 탑이 쏜 신호는 아무도 수신하지 않습니다. [3] 번째 탑이 쏜 신호는 2번째 탑이 수신합니다. [6] 번째 탑이 쏜 신호는 5번째 탑이 수신합니다. [7] 번째 탑이 쏜 신호는 6번째 탑이 수신합니다.
#include <string>
#include <vector>
using namespace std;
vector<int> solution(vector<int> heights) {
vector<int> answer(heights.size());
for (int i = heights.size() - 1; i >= 0; i--) {
for (int j = i - 1; j >= 0; j--) {
if (heights[i] < heights[j]) {
answer[i] = j+1;
break;
}
}
}
return answer;
}
lpPerformanceCount = 매개변수로 현재 성능 카운터 값을 계수로 받는 변수에 대한 포인터를 넘겨준다.
반환 값은 함수가 성공하면 0 이외의 값을 리턴하고 실패하면 0을 리턴한다.
(Windows XP 이상에서는 이 기능이 항상 성공해서 0을 리턴하는 경우는 없다.)
◎ LARGE_INTEGER
여기서 쓰이는 LARGE_INTEGER는 뭘까?
QueryPerformanceCounter나 QueryPerformanceFrequency같은 함수를 사용하기 위해선 크기가 큰 정수형이 필요하다.
왜? 더 자세한 시간값을 저장하기 위해서
그래서 windows.h에 포함돼 있는 LARGE_INTEGER가 그와 같은 것이다.
부호가 있는 64비트 정수형 데이터를 저장하기 위해 선언된 사용자 정의 자료형.
LARGE_INTEGER는 구조체인데 그 안을 들여다 보면
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart; // 32bit 정수형
LONG HighPart; // 32비트 정수형
} DUMMYSTRUCTNAME;
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart; // 64비트 정수형
} LARGE_INTEGER;
이렇게 되어 있다.
컴파일러가 64비트를 지원할 땐 64비트 정수형 변수에, 32비트 지원 시에는 32비트 정수형 변수에 64비트 측정값을 나눠 저장한다.
값은 64비트의 부호있는 정수형인 QuardPart에 저장되는 것이며
LowPart는 하위 32비트 DWORD형, HighPart는 상위 32비트 LONG 형이다.
64비트 중 LowPart(32bit)와 HighPart(32bit)를 둘다 사용함으로써 더 큰값을 사용할 수 있다.
◎ 사용법
#include <windows.h>
int main()
{
LARGE_INTEGER timer, start, end;
float DeltaTime;
QueryPerformanceFrequency(&timer); // 타이머의 주파수를 얻어온다.
QueryPerformanceCounter(&start); // 시작 시점의 CPU 클럭 수
// 실행할 내용
QueryPerformanceCounter(&end); // 종료 시점의 CU 클럭 수
DeltaTime = (end.QuadPart - start.QuadPart) / (float)timer.QuadPart; // 걸린 시간 계산
}
OO 연구소는 한 번에 K 칸을 앞으로 점프하거나, (현재까지 온 거리) x 2 에 해당하는 위치로 순간이동을 할 수 있는 특수한 기능을 가진 아이언 슈트를 개발하여 판매하고 있습니다. 이 아이언 슈트는 건전지로 작동되는데, 순간이동을 하면 건전지 사용량이 줄지 않지만, 앞으로 K 칸을 점프하면 K 만큼의 건전지 사용량이 듭니다. 그러므로 아이언 슈트를 착용하고 이동할 때는 순간 이동을 하는 것이 더 효율적입니다. 아이언 슈트 구매자는 아이언 슈트를 착용하고 거리가 N 만큼 떨어져 있는 장소로 가려고 합니다. 단, 건전지 사용량을 줄이기 위해 점프로 이동하는 것은 최소로 하려고 합니다. 아이언 슈트 구매자가 이동하려는 거리 N이 주어졌을 때, 사용해야 하는 건전지 사용량의 최솟값을 return하는 solution 함수를 만들어 주세요.
예를 들어 거리가 5만큼 떨어져 있는 장소로 가려고 합니다. 아이언 슈트를 입고 거리가 5만큼 떨어져 있는 장소로 갈 수 있는 경우의 수는 여러 가지입니다.
처음 위치 0 에서 5 칸을 앞으로 점프하면 바로 도착하지만, 건전지 사용량이 5 만큼 듭니다.
처음 위치 0 에서 2 칸을 앞으로 점프한 다음 순간이동 하면 (현재까지 온 거리 : 2) x 2에 해당하는 위치로 이동할 수 있으므로 위치 4로 이동합니다. 이때 1 칸을 앞으로 점프하면 도착하므로 건전지 사용량이 3 만큼 듭니다.
처음 위치 0 에서 1 칸을 앞으로 점프한 다음 순간이동 하면 (현재까지 온 거리 : 1) x 2에 해당하는 위치로 이동할 수 있으므로 위치 2로 이동됩니다. 이때 다시 순간이동 하면 (현재까지 온 거리 : 2) x 2 만큼 이동할 수 있으므로 위치 4로 이동합니다. 이때 1 칸을 앞으로 점프하면 도착하므로 건전지 사용량이 2 만큼 듭니다.
위의 3가지 경우 거리가 5만큼 떨어져 있는 장소로 가기 위해서 3번째 경우가 건전지 사용량이 가장 적으므로 답은 2가 됩니다.
입출력 예
N
Result
5
2
6
2
5000
5
입출력 예 설명
입출력 예 #1 위의 예시와 같습니다.
입출력 예 #2 처음 위치 0 에서 1 칸을 앞으로 점프한 다음 순간이동 하면 (현재까지 온 거리 : 1) x 2에 해당하는 위치로 이동할 수 있으므로 위치 2로 이동합니다. 이때 1 칸을 앞으로 점프하면 위치3으로 이동합니다. 이때 다시 순간이동 하면 (현재까지 온 거리 : 3) x 2 이동할 수 있으므로 위치 6에 도착합니다. 이 경우가 건전지 사용량이 가장 적으므로 2를 반환해주면 됩니다.
입출력 예 #3 위와 같은 방식으로 합니다.
#include <iostream>
using namespace std;
int solution(int n)
{
int ans = 0;
int remain_meter = n;
for (int i = remain_meter; i > 0; i /= 2) {
if (i % 2 == 1) {
ans += 1;
}
}
return ans;
}
SIMD 처리는 데이터를 SIMD 레지스터에 load하고 결과를 추출하기 전에 완전히 처리할 때 가장 효율적이다.
SIMD processing is most efficient when data is loaded into the SIMD registers and fully processed before extracting the results.
스칼라와 벡터 형식 간의 변환은 비효율적이므로 필요할 때만 수행하는 것이 좋다.
Conversion between scalar and vector forms is inefficient, so we recommend that you do it only when required.
이러한 이유로 스칼라 값을 생성하는 DirectXMath 라이브러리의 함수는 스칼라 결과가 결과 벡터에 복제되는 벡터 형태로 리턴된다.
For this reason, functions in the DirectXMath library that produce a scalar value are returned in a vector form where the scalar result is replicated across the resulting vector
그래서 스칼라 값이 필요한 경우에 이와 같은 내용을 수행하는 방법에 대한 몇 가지 선택사항으로 XMFLOAT를 이용해 벡터를 메모리 구조에 저장하고 다시 읽어오는 방식을 사용.
SIMD의 장점을 이용하려면 함수에 XMVECTOR 형식의 매개변수를 전달할 때 지켜야 할 규칙이 있다.
이 규칙들은 플랫폼바다 다른데 플랫폼 독립적 코드를 위해 XMVECOTR 형식의 매개변수에 대해 CXMVECTOR, FXMVECTOR 형식을 사용한다.
Windows의 경우
// 32비트 Windows
typedef const XMVECTOR FXMVECTOR;
typedef const XMVECTOR& CXMVECTOR;
//64비트 Windows
typedef const XMVECTOR& FXMVECTOR;
typedef const XMVECTOR& CXMVECTOR;
이 둘의 차이는 XMVECTOR의 복사본을 직접 전달할 수 있는지, 참조를 전달해야 하는지이다.
구체적인 또 하나의 규칙은 한 함수의 처음 세 개의 XMVECTOR 매개변수는 반드시 FXMVECTOR형식이어야 한다. 그 외의 XMVECTOR 매개변수는 반드시 CXMVECOTR 형식이여야 한다.
예를 들어 7개의 매개변수를 받는 함수가 있으면 위의 규칙에 따라 처음 세 개는 FXMVECTOR, 나머지 네 개는 CXMVECOTR 형식이어야 하며 XMVECTOR 매개변수들 사이에 다른 매개변수가 끼어있을 경우에도 처음 세 개의 XMVECTOR 매개변수는 반드시 FXMVECTOR 형식이고 나머지 XMVECTOR 매개변수는 CXMVECOTR 형식이어야 한다.
또한 상수(const) XMVECTOR 인스턴스에는 반드시 XMVECTORF32 형식을 사용해야 한다.
초기화 구문을 사용하고자 할 때에는 항상 XMVECTORF32를 사용해야 한다.
XMVECTORF32는 16바이트 경계로 정렬된 구조체로, XMVECTOR로의 변환 연산자를 지원한다.
◎ 기타 제공 함수
XNA Math 라이브러리는 XMVECTOR를 이용한 벡터 덧셈, 뺄셈, 스칼라 곱셈을 위해 중복적재된 연산자들을 제공한다.
또한 XNA Math 라이브러리는 벡터의 길이, 벡터 길이의 제곱, 두 벡터의 내적, 두 벡터의 외적, 벡터 정규화를 위한 편의용 함수들도 제공한다.