드래곤 앤 던전

[Gold IV] 드래곤 앤 던전 - 16434

문제 링크

성능 요약

메모리: 2564 KB, 시간: 160 ms

분류

이분 탐색, 구현

제출 일자

2023년 12월 28일 11:35:51

문제 설명

용사는 공주를 구하기 위해 무시무시한 용이 있는 던전으로 향하기로 하였습니다. 우선 용사는 용사 자신과 던전을 분석하였습니다.

용사에게는 세 종류의 능력치가 있습니다.

  • HMaxHP : 용사의 최대 생명력입니다. 이 값은 1이상이어야 하며 던전에 들어간 이후로 변하지 않습니다.
  • HCurHP : 현재 용사의 생명력입니다. 던전에 들어가기 전 이 값은 용사의 최대 생명력 HMaxHP와 같습니다. 이 값은 HMaxHP보다 커질 수 없습니다.
  • HATK : 용사의 공격력입니다.

던전은 총 N개의 방으로 이루어져 있고 i번째 방을 통해서만 i+1번째 방으로 이동 할 수 있습니다. 방에는 포션이 있거나 몬스터가 있는데 몬스터가 있을 경우 몬스터를 쓰러트려야지 다음방으로 이동 할 수 있습니다. N번째 방에는 공주와 용이 있고, 용을 무찌르면 공주를 구할 수 있습니다.

몬스터가 있는 방에 올 경우 다음과 같이 전투가 진행됩니다.

  1. 용사의 공격력 HATK만큼 몬스터의 생명력을 깎습니다.
  2. 몬스터의 생명력이 0 이하이면 전투가 종료되고 용사는 다음 방으로 이동합니다.
  3. 몬스터의 공격력만큼 용사의 생명력 HCurHP를 깎습니다.
  4. 용사의 생명력이 0 이하이면 전투가 종료되고 용사는 사망합니다.
  5. 다시 1부터 진행합니다.

포션이 있는 방에 올 경우 포션을 마셔서 현재 용사의 생명력 HCurHP가 일정량 회복되고 공격력 HATK도 일정량만큼 증가됩니다. 회복된 생명력이 최대 생명력 HMaxHP보다 큰 경우 용사의 현재 생명력 HCurHP가 최대 생명력 HMaxHP와 같아집니다.

용사는 던전으로 향하기 전에 만반의 준비를 하고 있습니다. 용사는 수련을 하면 최대 생명력 HMaxHP를 늘릴 수 있는데 얼마나 수련해야 할지 고민입니다.

용사는 N번 방에 있는 용을 쓰러트리기 위한 최소의 HMaxHP를 여러분이 계산해주면 좋겠다고 합니다.

입력

첫 번째 줄에 방의 개수 N (1 ≤ N ≤ 123,456) 과 용사의 초기 공격력 HATK (1 ≤ HATK ≤ 1,000,000) 가 주어집니다.

i+1번째 줄엔 i번째 방의 정보를 나타내는 세개의 정수 ti, ai, hi (ti ∈ {1, 2}, 1 ≤ ai, hi ≤ 1,000,000) 가 주어집니다.

ti가 1인 경우 공격력이 ai이고 생명력이 hi인 몬스터가 있음을 나타내고, ti가 2인 경우 용사의 공격력 HATKai만큼 증가시켜주고 용사의 현재 생명력 HCurHPhi만큼 회복시켜주는 포션이 있음을 나타냅니다.

출력

용사가 N번째 방에 있는 용을 쓰러트리기 위한 최소의 HMaxHP를 출력합니다.

TIL

  • 자료형을 주의하자. 큰 입력 값을 받는 변수와 대입연산을 하는 변수 또한 그와 맞먹는 크기를 가지고 있어야 한다.
  • 결투를 하는 것을 while(1)문으로 무식하게 치고받고 하게 만들었는데, 이렇게 구현하면 원인모를 에러가 났었다. 따라서 나눗셈연산으로 진행하였는데, 이건 또 맞았다. 세부적인 차이는 추후 문제를 다시 풀때 확인해야 겠다.

FeedBack

  • binary search 자체는 잘 구현했는데, 결정함수에서 나오는 에러를 찾지 못해 많이 헤맸다. 특히 while(1)문을 쓰는 것보다는 그냥 나눗셈연산으로 진행하는 습관 필요.

내 접근

결투를 하는 걸 while(1)문으로 접근 long long 변수를 대입하는 변수가 int형이여서 오버플로우 발생 결투를 나눗셈연산으로 바꿈.

내 코드


#include <stdio.h>
#include <stdlib.h>

typedef struct {
	int num;
	char name[12];
}Tier;

int binarySearch(Tier* array, int size, int target);



int main()
{
	//input
	int N, M;
	scanf("%d %d", &N, &M);
	Tier* tiers = (Tier*)malloc(sizeof(Tier) * N);
	for (size_t i = 0; i < N; i++)
		scanf("%s %d", tiers[i].name, &tiers[i].num);
	int* attacks = (int*)malloc(sizeof(int) * M);
	for (size_t i = 0; i < M; i++)
		scanf("%d",&attacks[i]);
	
    //get
	for (size_t i = 0; i < M; i++) {
		binarySearch(tiers,N,attacks[i]);
	}
	
	free(tiers);
	free(attacks);

	return 0;
}



int binarySearch(Tier* array, int size, int target) {
	int left = 0, right = size - 1;
	int mid=0;
	while (right >= left) {
		mid = (left + ri#include <stdio.h>
#include  <stdlib.h>
#include <stdbool.h>
#define MAX 1000000000000000000
typedef struct {
	int type;
	int attack;
	int health;
}ROOM;

int main() {

	//input
	int n, H_ATK;
	scanf("%d %d", &n, &H_ATK);
	ROOM* rooms = (ROOM*)malloc(sizeof(ROOM) * n);
	for (size_t i = 0; i < n; i++)
		scanf("%d %d %d", &rooms[i].type, &rooms[i].attack, &rooms[i].health);

	unsigned long long low = 0, high = MAX;
	bool alive = true;
	while (low <= high) {

		alive = true;
		unsigned long long mid = low + (high - low) / 2;
		unsigned long long H_CurHP = mid;
		unsigned long long H_CurATK = H_ATK;
		//printf("low %ld mid %ld high %ld\n", low, mid, high);
		for (size_t i = 0; i < n && alive; i++) {
			if (rooms[i].type == 1) {
				int M_HP = rooms[i].health;
				int M_ATTACK = rooms[i].attack;
				unsigned long long M_dieTurn = M_HP / H_CurATK + ((M_HP % H_CurATK) > 0 ? 1 : 0);
				unsigned long long H_dieTurn = H_CurHP / M_ATTACK + ((H_CurHP % M_ATTACK) > 0 ? 1 : 0);
				if (M_dieTurn <= H_dieTurn) {//생존
					H_CurHP -= M_ATTACK * (M_dieTurn - 1);
				}
				else {
					alive = false;
				}
			}
			else {
				H_CurHP = H_CurHP + rooms[i].health > mid ? mid : H_CurHP + rooms[i].health;
				H_CurATK += rooms[i].attack;
			}
		}

		if (alive) high = mid - 1;
		else low = mid + 1;

	}

	printf("%lld", low);


	return 0;

추후에 다시 풀어야 할 문제이다.

Categories:

Updated:

Leave a comment