[백준] 14226번 이모티콘 (= emoticon) - 재우스 프로그래밍 (C 언어)
2021. 1. 29. 11:18ㆍ백준
문제 링크 : www.acmicpc.net/problem/14226
#include <stdio.h>
#include <stdbool.h>
#define DEBUG 0
#define MAX_QUEUE_SIZE 16000
#define MAX_INPUT_SIZE 1000
typedef struct _Node {
int mScreen;
int mClipBoard;
int mSecond;
} Node;
Node startNode;
typedef struct _Queue {
Node arrQueue[MAX_QUEUE_SIZE + 2];
int front;
int back;
} Queue;
Queue queue;
//노드의 [screen에 출력된 이모티콘 개수][clipboard에 저장된 이모티콘 개수]로 노드의 방문 여부 체크
bool visited[MAX_INPUT_SIZE + 2][MAX_INPUT_SIZE + 2];
void BFS(Node); //queue의 front 노드에 대해서 화면의 이모티콘 삭제 or 클립보드에 현재 화면의 이모티콘 개수 복사 or 클립보드에 있는 이모티콘을 화면에 복사 붙여넣기를 BreadthFirstSearch 알고리즘 방식을 탐색
void push(Node);
bool empty(void);
void initNode(Node *);
void initQueue();
void initVisited();
#if DEBUG
void printNode(Node);
void printQueue(void);
#endif
int main(void)
{
Node tempNode;
initNode(&tempNode);
tempNode.mScreen = 1;
initNode(&startNode);
initQueue();
initVisited();
scanf("%d", &startNode.mScreen);
BFS(tempNode);
printf("%d\n", queue.arrQueue[queue.back].mSecond);
return 0;
}
void BFS(Node inputNode)
{
Node tempNode;
initNode(&tempNode);
queue.front++;
queue.back++;
push(inputNode); //인자로 들어온 node push
while (!empty()) {
inputNode = queue.arrQueue[queue.front]; //queue의 front에 있는 node값 가져옴
tempNode = inputNode; //inputNode 값 변경하기 전에 tempNode에 저장
//화면에 있는 이모티콘 하나를 삭제하는 경우
//화면에 이모티콘이 2개도 안되면 경우의 수를 따질 필요가 없고 &&
//화면의 이모티콘 개수, 클립보드에 저장된 이모티콘 개수 조합이 동일한 곳을 탐색한 적이 없을 때 실행
if (inputNode.mScreen - 1 >= 2 && !visited[inputNode.mScreen - 1][inputNode.mClipBoard]) {
inputNode.mScreen--; //화면 이모티콘 개수 한개 감소
inputNode.mSecond++; //1초 증가
queue.back++; //queue에 push하기 전 back 1 증가
push(inputNode); //queue에 화면 이모티콘 한 개 감소한 경우 push
visited[inputNode.mScreen][inputNode.mClipBoard] = true; //화면 이모티콘 한 개 감소하고, 클립보드에 저장된 이모티콘 개수는 그대로인 경우의 수 방문 체크
//최종 화면 이모티콘 개수와 동일하면 BFS 함수 return
if (inputNode.mScreen == startNode.mScreen) {
return;
}
}
inputNode = tempNode; //위에서 inputNode 값이 변경되었으므로 변경 전 값으로 다시 저장
//클립보드에 저장된 이모티콘 개수가 화면에 있는 이모티콘 개수와 다를 때 클립보드 갱신 && inputNode의 화면 이모티콘 개수를 클립보드에 갱신했을 때를 방문했었는지 체크
if (inputNode.mScreen != inputNode.mClipBoard && !visited[inputNode.mScreen][inputNode.mScreen]) {
inputNode.mClipBoard = inputNode.mScreen; //클립보드 이모티콘 개수 갱신
inputNode.mSecond++; //1초 증가
queue.back++; //queue에 push하기 전 back 1 증가
push(inputNode); //queue에 클립보드 개수 갱신한 경우 push
visited[inputNode.mScreen][inputNode.mScreen] = true; //클립보드 이모티콘 개수와 현재 화면 개수와 동일한 경우 방문 체크
/*
//최종 화면 이모티콘 개수와 동일하면 BFS 함수 return
if (inputNode.mScreen == startNode.mScreen) {
return;
}
*/
}
inputNode = tempNode; //위에서 inputNode 값이 변경되었으므로 변경 전 값으로 다시 저장
//클립보드에 저장된 이모티콘 개수만큼 화면에 추가했을 때 화면에 출력 가능한 최대 이모티콘 개수보다 적은 경우 &&
//방문한적 있는지 체크
if (inputNode.mScreen + inputNode.mClipBoard <= MAX_INPUT_SIZE && inputNode.mClipBoard > 0 && !visited[inputNode.mScreen + inputNode.mClipBoard][inputNode.mClipBoard]) {
inputNode.mScreen += inputNode.mClipBoard; //화면 이모티콘 개수 + 클립보드 이모티콘 개수로 갱신
inputNode.mSecond++; //1초 증가
queue.back++; //queue에 push하기 전 back 1 증가
push(inputNode); //queue에 클립보드 개수 갱신한 경우 push
visited[inputNode.mScreen][inputNode.mClipBoard] = true; //바뀐 경우 방문했다고 체크해줌.
//최종 화면 이모티콘 개수와 동일하면 BFS 함수 return
if (inputNode.mScreen == startNode.mScreen) {
return;
}
}
queue.front++; //queue의 front 증가
}
return;
}
bool empty(void)
{
if (queue.front > queue.back) {
return true;
}
else {
return false;
}
}
void push(Node inputNode)
{
queue.arrQueue[queue.back] = inputNode;
#if DEBUG
printf("push\t");
printNode(inputNode);
printf("queue\n");
printQueue();
#endif
return;
}
void initNode(Node *inputNode)
{
inputNode->mScreen = 0;
inputNode->mClipBoard = 0;
inputNode->mSecond = 0;
return;
}
void initQueue()
{
for (int i = 0; i < MAX_QUEUE_SIZE + 2; i++) {
initNode(&queue.arrQueue[i]);
}
queue.front = -1;
queue.back = -1;
return;
}
void initVisited()
{
for (int i = 0; i < MAX_INPUT_SIZE + 2; i++) {
for (int j = 0; j < MAX_INPUT_SIZE + 2; j++) {
visited[i][j] = false;
}
}
}
#if DEBUG
void printNode(Node inputNode)
{
printf("node: %d\t%d\t%d\n", inputNode.mScreen, inputNode.mClipBoard, inputNode.mSecond);
return;
}
void printQueue()
{
for (int i = 0; i < startNode.mScreen; i++) {
printNode(queue.arrQueue[i]);
}
printf("front: %d, back: %d\n", queue.front, queue.back);
return;
}
#endif
'백준' 카테고리의 다른 글
[백준] 12865번 평범한 배낭 (= plain backpack) - 재우스 프로그래밍 (C 언어) (0) | 2021.01.30 |
---|---|
[백준] 15954번 인형들 (= dolls) - 재우스 프로그래밍 (C 언어) (0) | 2021.01.30 |
[백준] 1967번 트리의 지름 (= tree diameter) - 재우스 프로그래밍 (C 언어) (0) | 2021.01.29 |
[백준] 1062번 가르침 (= teaching) - 재우스 프로그래밍 (C 언어) (0) | 2021.01.29 |
[백준] 2146번 다리 만들기 (= bridge building) - 재우스 프로그래밍 (C 언어) (0) | 2021.01.29 |