안녕하세요 정말 오랜만에 찾아뵙는 알고리즘 풀이입니다!
오늘은 if문 분류로 되어있는 문제로 가져왔어요.
출처: COCI 2009/2010년도 7th round 1번 문항
출처: 백준 2884번
정답률: 40.588%
[2884번] 알람 시계 (SPAVANAC)
문제
상근이는 매일 아침 알람을 듣고 일어난다. 알람을 듣고 일어나면 다행이겠지만, 항상 조금만 더 자려는 마음 때문에 매일 학교를 지각하고 있다. 상근이는 모든 방법을 동원해보았지만, 조금 더 자려는 마음은 그 어떤 것도 없앨 수 없었다. 이런 상근이를 불쌍하게 보던, 창영이는 자신이 사용하는 방법을 추천해주었다. 바로 "45분 일찍 알람 설정하기"이다. 이 방법은 단순하다. 원래 설정되어 있는 알람을 45분 앞서는 시간으로 바꾸는 것이다. 어차피 알람 소리를 들으면, 알람을 끄고 조금 더 잘 것이기 때문이다. 이 방법을 사용하면 매일 아침 더 잤다는 기분을 느낄 수 있고, 학교도 지각하지 않게 된다. 현재 상근이가 설정한 알람 시각이 주어졌을 때, 창명이의 방법을 사용한다면, 이를 언제로 고쳐야 하는지 구하는 프로그램을 작성하시오.
입출력
입력:
첫째 줄에 두 정수 H와 M이 주어진다. (0 <= H <= 23, 0<=M<=59) 그리고 이것은 현재 상근이가 설정해 놓은 알람 시간 H시 M분을 의미한다. 입력 시간은 24시간 표현을 사용한다. 24시간 표현에서 하루의 시작은 0:0(자정)이고 끝은 23:59(다음날 자정 1분 전)이다. 시간을 나타낼 때, 불필요한 0은 사용하지 않는다.
출력:
첫째 줄에 상근이가 창영이의 방법을 사용할 때, 설정해야 하는 알람 시간을 출력한다. (입력과 같은 형태로 출력하면 된다.)
같이 풀어봅시다~~!
ANSWER 해설
해당 문제는 규칙만 알면 너무 쉬워요. 정말 너무 쉬운....
가장 먼저, 만약 현재 시간이 45분보다 크면 그냥 현재 분에서 45분을 빼주면 되겠죠? 시간은 그대로일거고...
[C++]
#include <iostream>
using namespace std;
int main()
{
const int setting = 45; //문제에서 주어진 값
int hour, min; //입력받을 값 선언
cin >> hour >> min; //시간과 분을 입력받음
if(min >= setting) min -= 45;
return 0;
}
그럼 만약 현재 시간이 45분보다 작다면 어떻게 계산할 수 있을까요?
우리 빼기 할 때, 빼기 모자르면 앞에서 10 빌려와서 빼죠? 14 - 7 하면, 일의자리에서 계산한다고 할 때 4에서 7을 못빼니까 앞에 1을 빌려와서 10에서 7을 뺀 뒤 계산한 값의 3과 남은 4를 더해서 7! 이렇게 하잖아요.
뭐 시간도 마찬가지겠죠. 첫 번째 예제의 경우 10분에서 45분을 뺄 수 없어요. 그니까 60분을 빌려와서 (60-45)+10 = 25 ! 이렇게하면 제대로된 계산을 할 수 있습니다. 물론 빌려왔으니까 시간은 -1 해줘야겠죠.
근데 주의할 점이 있어요. 2번째 예제처럼 0시일 경우 거꾸로 가서 23시가 되어야해요. 시계는 순환하기 때문이죠. 그러므로 아래처럼 작성해줄 수 있습니다.
[C++ 전체 소스코드]
#include <iostream>
using namespace std;
int main()
{
const int setting = 45;
int hour, min = 0;
cin >> hour >> min;
if (min < setting)
{
min = (min + 60 - setting);
hour = (hour + 24 - 1) % 24;
}
else
{
min -= setting;
}
cout<<hour<<" "<<min;
return 0;
}
이게 별거 아닌데 좀 길어보인다, 그럼 아래처럼 작성줄 수 있어요.
[C++ 전체 소스코드]
#include <iostream>
using namespace std;
int main()
{
const int setting = 45;
int hour, min = 0;
cin >> hour >> min;
min -= setting;
if (min < 0)
{
min += 60;
hour = (hour + 24 - 1) % 24;
}
printf("%d %d", hour, min);
return 0;
}
일단, 45분을 빼준다음에 마이너스이면, 시간을 내려야하는거니까~!
계산 순서 차이일뿐 똑같은 로직입니다.
[C언어]
C언어라면 단순히 cin이나 cout대신 scanf, printf 만 써주면 돼요 ㅎㅎ 딱히 언어를 구별지을만한 코드가 들어가진 않았으므로..?
그렇다면 다른 방법으로 풀어봅시다. 이번에는 비율적인 관점으로 가볼게요. 시계는 빙글 빙글 돌아요.
여기서 45분이 앞섰다는건, 4분의 3이 앞섰다는거고, 그건 4분의 1, 즉 15분만큼 앞으로 갔다는거랑 같은 말이죠 (분만 따졌을 때)
사실 앞에 코드랑도 결국 같은 말이예요 (60-45)+10 은 결국 15 + 10 이니까 10분에 15를 더한거랑 똑같잖아요?!
[C언어 전체코드]
#include <stdio.h>
int main(){
int h, m;
scanf("%d %d", &h, &m);
printf("%d %d", (h+23+(m+15)/60)%24, (m+15)%60);
}
따라서 분은 (m+15)%60으로 구해도 같은말~~~
시간도 24시 기준이니까 24시 이상 나왔을 경우 변경을 위해 모듈로 나눠줍시다.
[JAVA 자바]
남은 것은 자바인가..! 원리는 똑같, 언어만 다를 뿐
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int hour = Integer.parseInt(st.nextToken());
int min = Integer.parseInt(st.nextToken());
min -= 45;
if (min <0)
{
min +=60; hour -= 1;
if(hour<0) hour = 23; //위에처럼 모듈 안쓰고 이렇게 단순하게 해줘도 됨
}
System.out.println(hour+" "+min);
}
}
[시간 76ms, 코드길이 698B]
사실 속도때문에 저 버퍼드리더를 쓴거지, 아래처럼 그냥 스캐너로 입력받아도 됩니다.
import java.io.IOException;
import java.util.Scanner;
public class Main{
public static void main(String[] args) throws IOException{
Scanner sc = new Scanner(System.in);
int hour = sc.nextInt();
int min = sc.nextInt();
min -= 45;
if (min <0)
{
min +=60; hour -= 1;
if(hour<0) hour = 23; //위에처럼 모듈 안쓰고 이렇게 단순하게 해줘도 됨
}
System.out.println(hour+" "+min);
}
}
[시간 104ms, 코드길이 475B]
다른 사람 풀이 참조하기
오늘은 여기까지입니다. 도움이 되셨다면 좋아요, 덧글 또는 광고보답은 어떤가요?
'별걸다하는 IT > 알고리즘 문제풀이' 카테고리의 다른 글
ACM 호텔 문제 풀이 및 해설 C, C++, JAVA [백준 10250번, ACM ICPC 2014 기출] (0) | 2020.09.15 |
---|---|
[C/C++/JAVA 문자열 단어수 문제] 문자열에서 단어가 몇 개인지 세기 (문자열에 공백 포함) (0) | 2020.08.30 |
[COCI 2009/2010기출, 백준 2884번] 알람 시계 문제 풀이 및 해설 (C/C++/Java) 문제 해설 (0) | 2020.03.24 |
[ACM ICPC 기출, 백준 2292번] 벌집 문제 풀이 및 해설 (C++/Java 문제 풀기~) (0) | 2019.11.13 |
[COCI 2012/2013 기출, 백준 5622번] 다이얼 문제 해설 및 C/C++,자바 풀이 (2) | 2019.11.06 |
[COCI 2009/2010기출, 백준 알고리즘] FILIP, 2908번 상수 문제 해설 및 문제 풀이(C/C++/자바) (0) | 2019.11.03 |
최신 댓글