이전 문제보다는 조금 코딩 난이도가 올라간 문제이다. 문제 전문은 다음과 같다:


정리하면,
이렇게 4가지의 오류가 있다.
짠 코드를 보면서 설명하도록 하겠다.
#include <stdio.h>
#include <stdlib.h>
typedef struct log_file {
	int time;
	int user;
	int race;
}Log;
int main() {
	int user_num, log_num;
	scanf("%d %d", &user_num, &log_num);
	Log* inputlog = (Log*)malloc(sizeof(Log) * log_num);
	int* user_arr = (int*)calloc(user_num, sizeof(int));
	int* user_status = (int*)malloc(sizeof(int) * user_num);
	for (int i = 0; i < user_num; i++) {
		user_status[i] = -1;
	}
	for (int i = 0; i < log_num; i++) {
		scanf("%d %d %d", &inputlog[i].time, &inputlog[i].user, &inputlog[i].race);
	}
	int i;
	for (i = 0; i < log_num; i++) {
		if (user_status[inputlog[i].user - 1] == inputlog[i].race) { // 현재 상태와 로그의 상태가 같은 경우
			printf("NO");
			break;
		}
		else if (user_status[inputlog[i].user - 1] == 0 && inputlog[i].race == 1){ // 현재 상태 = 0, 로그 상태 = 1 -> 레이스를 끝낸 경우
			if (inputlog[i].time - user_arr[inputlog[i].user - 1] < 60) { // 레이스를 끝냈는데, 그 차이가 60초 미만일 경우
				printf("NO");
				break;
			}
			user_status[inputlog[i].user - 1] = inputlog[i].race;
		}
		else { // 위의 경우가 모두 아니면, user_arr, user_status에 적절한 값을 대입한다. 
			user_arr[inputlog[i].user - 1] = inputlog[i].time;
			user_status[inputlog[i].user - 1] = inputlog[i].race;
		}
	}
	int j;
	if (i == log_num) { 
		for (j = 0; j < user_num; j++) {
			if (user_status[j] != 1) { // 끝난 상태가 1이 아닌 경우
				printf("NO");
				break;
			}
		}
		if (j == user_num) { // 모든 조건을 만족하고 나왔을 때, YES를 출력한다. 
			printf("YES");
		}
	}
	free(inputlog);
	free(user_arr);
	free(user_status);
	return 0;
}
테스트해보지 않아서 정확한 코드인지는 알 수 없지만, 이러한 코드를 만들게 되었다
typedef struct log_file {
	int time;
	int user;
	int race;
}Log;
이 부분은 구조체 배열을 만들기 위한 구조체이다. Log는 별칭으로 쓰인다.
Log* inputlog = (Log*)malloc(sizeof(Log) * log_num);
int* user_arr = (int*)calloc(user_num, sizeof(int));
int* user_status = (int*)malloc(sizeof(int) * user_num);
각 배열을 동적 할당으로 구분한다.
inputlog 배열은, 로그 상태인 t, i, s를 입력받는 배열이다.
user_arr 배열은, 각 index가 유저 번호 - 1이고, 값은 로그 값의 시간을 갖는 배열이다.
user_status 배열은, 각 유저의 상태, 즉 게임을 시작했는지 끝냈는지를 받는 배열이다. user_status 배열은 그 바로 밑의 문에서 -1로 초기화해주었는데, 그 이유는 뒤쪽에 나온다. 
if (user_status[inputlog[i].user - 1] == inputlog[i].race) { // 현재 상태와 로그의 상태가 같은 경우
	printf("NO");
	break;
}
inputlog[i].user는 입력받은 로그에서의 user 번호를 뜻한다. 배열에 값을 저장할 때 우리는 기본적으로 0부터 저장하고, user 값은 1부터 시작한다. 그러므로 1을 빼준 값이 user_status 배열의 index가 된다. inputlog[i].race 값은, 입력받은 로그에서의 레이스 시작 여부를 뜻한다. 이는 0 또는 1로 되어있고, 처음 user_status 배열을 초기화할 때 -1로 초기화했으므로, 우리는 처음 값이 비교될 때 NO를 출력하고 빠져나올 일은 없다고 생각하면 된다.
else if (user_status[inputlog[i].user - 1] == 0 && inputlog[i].race == 1){ // 현재 상태 = 0, 로그 상태 = 1 -> 레이스를 끝낸 경우
	if (inputlog[i].time - user_arr[inputlog[i].user - 1] < 60) { // 레이스를 끝냈는데, 그 차이가 60초 미만일 경우
		printf("NO");
		break;
	}
	user_status[inputlog[i].user - 1] = inputlog[i].race;
}
위의 코드와 이어지는 코드이다. 만약 현재 상태가 0이고, 로그에서 1의 상태를 받는다면 레이스를 시작하고 제대로 끝났다는 뜻이므로, else if 문 안으로 들어오게 된다. 만약, 끝나긴 끝났지만 그 차이가 60초 미만이라면, 그 바로 밑의 if문에 걸려서 break 문을 만나게 되지만, 그렇지 않는다면 user_status에서의 유저 index에 현재 상태인 1을 넣어주게 된다.
else { // 위의 경우가 모두 아니면, user_arr, user_status에 적절한 값을 대입한다. 
	user_arr[inputlog[i].user - 1] = inputlog[i].time;
	user_status[inputlog[i].user - 1] = inputlog[i].race;
}
위 if와 else if문의 경우가 모두 아니라면, 새로운 값을 대입해준다. user_arr에는 시작 시간을 넣어주고, user_status에는 시작 상태, 즉 0을 대입해준다.
if (i == log_num) { 
	for (j = 0; j < user_num; j++) {
		if (user_status[j] != 1) { // 끝난 상태가 1이 아닌 경우
			printf("NO");
			break;
		}
	}
	if (j == user_num) { // 모든 조건을 만족하고 나왔을 때, YES를 출력한다. 
		printf("YES");
	}
}
위의 if 문에서 걸러지지 않는 것들이 있다. 그것이 바로, 시작 상태인 0을 입력받은 후 종료 상태인 1을 입력받지 않는 것들이다. 이런 것들을 걸러내기 위해, 우리는 user_status를 한번 훑어본다. 모든 user_status가 1이면, 모든 유저가 종료 상태이기 때문에 YES를 자신 있게 출력해주면 된다.
이 문제를 조금 쉽게 접근하려면, 기본적으로 유저의 상태는 0과 1을 반복해서 나오고, 끝은 무조건 1이어야 한다는 것을 인지하여야 한다. 0 다음에 0이 나오는 것도 안되고, 1 다음에 1이 나오는 것도 안되며, 1 다음에 0이 나온 후 종료되는 것도 안된다. 이것을 잘 이용하면, 조금 더 간단한 코드가 나올 수도 있을 것 같다.