[백준] 1476번 날짜 계산
- 알고리즘/백준
- 2020. 5. 25. 20:00
문제
준규가 사는 나라는 우리가 사용하는 연도와 다른 방식을 이용한다. 준규가 사는 나라에서는 수 3개를 이용해서 연도를 나타낸다. 각각의 수는 지구, 태양, 그리고 달을 나타낸다.
지구를 나타내는 수를 E, 태양을 나타내는 수를 S, 달을 나타내는 수를 M이라고 했을 때, 이 세 수는 서로 다른 범위를 가진다. (1 ≤ E ≤ 15, 1 ≤ S ≤ 28, 1 ≤ M ≤ 19)
우리가 알고있는 1년은 준규가 살고있는 나라에서는 1 1 1로 나타낼 수 있다. 1년이 지날 때마다, 세 수는 모두 1씩 증가한다. 만약, 어떤 수가 범위를 넘어가는 경우에는 1이 된다.
예를 들어, 15년은 15 15 15로 나타낼 수 있다. 하지만, 1년이 지나서 16년이 되면 16 16 16이 아니라 1 16 16이 된다. 이유는 1 ≤ E ≤ 15 라서 범위를 넘어가기 때문이다.
E, S, M이 주어졌고, 1년이 준규가 사는 나라에서 1 1 1일때, 준규가 사는 나라에서 E S M이 우리가 알고 있는 연도로 몇 년인지 구하는 프로그램을 작성하시오.
입력
첫째 줄에 세 수 E, S, M이 주어진다. 문제에 나와있는 범위를 지키는 입력만 주어진다.
출력
첫째 줄에 E S M으로 표시되는 가장 빠른 연도를 출력한다. 1 1 1은 항상 1이기 때문에, 정답이 음수가 나오는 경우는 없다.
문제 분류가 수학이랑 중국인의 나머지 정리? 라고 적혀 있는데 사실
그딴거 난 모르겠고...
그냥 완탐으로 풀었다. 그러니까 부루트 포스로 풀었다.
드디어 내 힘으로 오랜만에 문제를 풀었다.ㅎㅎ
아무튼
#include <bits/stdc++.h>
using namespace std;
int E,S,M;
int go(int ee,int ss, int mm,int index) {
if (ee == E && ss == S && mm == M) {
return index;
}
if (ee == 15) {
ee = 1;
} else {
ee++;
}
if (mm == 19) {
mm = 1;
} else {
mm++;
}
if (ss == 28) {
ss = 1;
} else {
ss++;
}
return go(ee,ss,mm,index+1);
}
int main(void) {
cin >> E >> S >> M;
cout << go(0,0,0,0) << "\n";
}
완탐을 풀때 2가지 방법으로 문제를 해결할 수 있다.
하나는 반복문이고 또 다른 하나는 재귀다.
그 중에서도 재귀를 가지고 문제를 해결했다. 점점 재귀가 익숙해지는게 다행이다.
내가 왜 이런 방식을 선택한 이유는
ee, mm , ss가 전부 15 19 28 일때는 어떻게 될까?
ee만 15일때는
ee와 mm이 15,19일때는 전부 예외처리하는게 귀찮았다. 그래서 이렇게 하였다.
또한 == 으로 한 이유도 설명하자면
이 풀이 방법은 15가 넘어가는일이 없다. 왜냐하면 넘는 순간 1로 바꿔주기 때문이다.
그래서 ==을 선택했다.
마지막으로 알아야 할건 go(0,0,0,0)이다. 과거의 나는 이런 코드를 작성하려는 시도조차 하지 않았다. 왜냐하면 이렇게 흘러가는지 전혀 예측하지 못했기 때문이다.
아무튼 이걸 1 1 1 1 로 해도 값은 같아진다. 2 2 2 2는 안될껄? ㅎㅎ
왜냐하면 0년이라는 건 존재하지 않기 때문에 쓸대없는 재귀가 한번더 사용되기 때문에 결론적이면 1 1 1 1랑 같다.
이게 뭐냐면 index그러니까 이건 우리가 사용하는 연도다.
이게 계속 증가한다. 어떠한것도 영향을 받지 않고... 그렇기 때문에 이것을 return을 시켜 줄수 있었다.
그 전에도 파라미터를 리턴 시켜준다는 사실은 알고 있었지만,
왜 사용하는지 이해하지 못했다. 왜냐하면 값이 증가한걸 넣는걸 몰랐기 때문이다.
뭐 단순한 오해지만.. 이 단순한 오해 때문에 많은 문제를 풀지 못했다는 사실을 알고 난 후로는 슬프다.
#include <stdio.h>
int main(void) {
int E, S, M;
scanf("%d %d %d", &E, &S, &M);
E %= 15;
S %= 28;
M %= 19;
for (int i = 1; i > 0; i++) {
if (i % 15 == E && i % 28 == S && i % 19 == M) {
printf("%d", i);
return 0;
}
}
}
for문이 이해안가긴 하지만...
다른건 어떨까?
#include <bits/stdc++.h>
using namespace std;
typedef long long lint;
int main(){
int a, b, c;
cin >> a >> b >> c;
a--;
b--;
c--;
int dap = 1;
while(a || b || c){
a+=14;
b+=27;
c+=18;
a %= 15;
b %= 28;
c %= 19;
dap++;
}
cout << dap;
}
전부 달라 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
재밌군...
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 9093번 단어 뒤집기 (0) | 2020.05.28 |
---|---|
[백준] 17090번 미로 탈출하기 (0) | 2020.05.26 |
[백준] 1331번 나이트 투어 & 2251번 물통 (0) | 2020.05.24 |
[백준] 10987번 모음의 개수 (0) | 2020.05.22 |
[백준] 6679번 싱기한 네자리 숫자 (0) | 2020.05.19 |