*이 포스트에서 문제의 답안은 C언어로 구성했습니다.
#include <stdio.h>
#include <stdlib.h>
#ifndef __C_LINKED_LIST_H__
#define __C_LINKED_LIST_H__
#define TRUE 1
#define FALSE 0
typedef int Data;
typedef struct _node
{
Data data;
struct _node * next;
} Node;
typedef struct _CLL
{
Node * tail;
Node * cur;
Node * before;
int numOfData;
} CList;
typedef CList List;
void ListInit(List * plist);
void LInsert(List * plist, Data data);
void LInsertFront(List * plist, Data data);
int LFirst(List * plist, Data * pdata);
int LNext(List * plist, Data * pdata);
Data LRemove(List * plist);
int LCount(List * plist);
void ListInit(List * plist)
{
plist->tail = NULL;
plist->cur = NULL;
plist->before = NULL;
plist->numOfData = 0;
}
void LInsertFront(List * plist, Data data)
{
Node * newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
if (plist->tail == NULL)
{
plist->tail = newNode;
newNode->next = newNode;
}
else
{
newNode->next = plist->tail->next;
plist->tail->next = newNode;
}
(plist->numOfData)++;
}
void LInsert(List * plist, Data data)
{
Node * newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
if (plist->tail == NULL)
{
plist->tail = newNode;
newNode->next = newNode;
}
else
{
newNode->next = plist->tail->next;
plist->tail->next = newNode;
plist->tail = newNode;
}
(plist->numOfData)++;
}
int LFirst(List * plist, Data * pdata)
{
if (plist->tail == NULL) // 저장된 노드가 없다면
return FALSE;
plist->before = plist->tail-1;
plist->cur = plist->tail;
*pdata = plist->cur->data;
return TRUE;
}
int LNext(List * plist, Data * pdata)
{
if (plist->tail == NULL) // 저장된 노드가 없다면
return FALSE;
plist->before = plist->cur;
plist->cur = plist->cur->next;
*pdata = plist->cur->data;
return TRUE;
}
Data LRemove(List * plist)
{
Node * rpos = plist->cur;
Data rdata = rpos->data;
if (rpos == plist->tail) // 삭제 대상을 tail이 가리킨다면
{
if (plist->tail == plist->tail->next) // 그리고 마지막 남은 노드라면
plist->tail = NULL;
else
plist->tail = plist->before;
}
plist->before->next = plist->cur->next;
plist->cur = plist->before;
free(rpos);
(plist->numOfData)--;
return rdata;
}
int LCheck(List * plist)
{
if (plist->tail == NULL)
return 0;
if (plist->tail != NULL)
return 1;
}
int main(void) {
List list;
int n, k, count;
int data;
ListInit(&list);
scanf_s("%d %d", &n, &k);
for (int i = 1; i <= n;i++)
{ LInsert(&list,i );
}
LFirst(&list, &data);
printf("<");
do{
for (int i = 0; i < k;i++)
{
LNext(&list, &data);
}
printf("%d", data);
LRemove(&list);
count = LCheck(&list);
if (count == 0)break;
printf(", ");
} while (count != 0);
printf(">");
}
알아야 하는 함수 및 코드
printf
scanf
for
do while
조건연산자
연결리스트
조세퍼스의 원리
처음 문제를 읽으면 무슨 소리인가 싶은데 예제를 써보면서 원리를 이해하면 된다.
입력 : 7 3
7명 / 원형 3번째 자리 사람 제거
1 2 3 4 5 6 7 -> 3
4 5 6 7 1 2 -> 6
7 1 2 4 5 -> 2
4 5 7 1 -> 7
1 4 5 -> 5
1 4 -> 1 세 번째가 없고 원이므로 순환해서 3번째 인 대상이 선택된다. 즉 1 4 1.
4 -> 4 하나밖에 없으므로 그 하나가 순환 후의 세번째이다. 4 4 4.
출력 <3, 6, 2, 7, 5, 1, 4>
핵심은 3번째가 제거된 그 자리부터 순환이 반복된다는 것이다.
728x90
'공부 > 프로그래밍' 카테고리의 다른 글
[C언어] 별표로 달팽이 그리기 (0) | 2023.05.23 |
---|---|
[C언어] 백준 1991번 트리 순회 (2) | 2019.07.22 |
[C언어] 백준 5639번 이진 검색 트리 (0) | 2019.07.20 |
[C언어] 반복문 printf 출력에서 마지막엔 \n(줄바꿈) 안하게 하기 (0) | 2019.06.24 |
C++ .size() 써보기 (0) | 2019.05.28 |