https://www.acmicpc.net/problem/18312
문제 해답
#include<iostream>
using namespace std;
#define hour 24
#define min 60
#define sec 60
int main() {
int n, k;
cin >> n >> k;
long long total = 0;
int answer = 0;
long long end_time = (n + 1) * 60 * 60;
for (int t = 0; t < end_time; t++) {
int h, m, s;
long long tmp = 1;
s = t/(tmp) % sec;
m = t/(tmp*= sec) % min;
h = t/(tmp*=min) % hour;
printf("%d:%d:%d\n", h, m, s);
if (m%10 == k || m / 10 == k) {
answer++;
}
else if (s % 10 == k || s / 10 == k) {
answer++;
}
else if (h % 10 == k || h / 10 == k) {
answer++;
}
}
cout << answer << endl;
}
모든 시간을 최소 단위 기준으로 만든다.
(1분 -> 60초, 1시간 -> 60*60 초.....)
만약 1시 59분 59초를 표현하면 어떻게 될까?
시: 60*60
분: 59* 60
초: 59*1
즉, 만약 '초'가 60초가 넘어가면, '분'으로 넘어가고, '분'이 60분이 넘어가면 '시' 로 계산이 된다.
이를 역으로 계산할 때에도 아래와 같이, 시, 분, 초를 추출할 수 있다.
time= (60*60+58*60+59*1) -> time/(60*60*1)%24, time/(60*1)%60, time/(1)%60
즉, 어떤 시간을 time에서 다시 추출하기 위해선 현재시간/(해당 시간을 '초'로 환산시 단위)%(해당 시간의 최대 단위) 로 구할 수 있는 것이다.
아래와 같이 for문을 돌아서 해결하는 것도 가능하지만, 만약 시간과 시간 사이의 연산( A시각, B 시각은 어느정도 시각 차이?) 와 같은 문제를 만나면 위와 같이 long으로 묶어서 해결하는 것이 편할 것이다.
#include <iostream>
using namespace std;
int main(void) {
int N, K, num = 0;
cin >> N >> K;
for (int hour = 0; hour <= N; hour++) {
for (int minute = 0; minute < 60; minute++) {
for (int sec = 0; sec < 60; sec++) {
if (hour % 10 == K || hour / 10 == K ||
minute % 10 == K || minute / 10 == K ||
sec % 10 == K || sec / 10 == K)
num++;
}
}
}
cout << num;
}
또한, c++에는 time 관련 헤더가 있다. 서칭해서 찾은 관련 글을 아래에 정리했으니, 참고하는 것도 좋다.
하지만, 코딩 테스트 문제에서는 ,헤더 사용을 막기위해, 시간의 단위를 다르게 할 수 도 있다.( 매 달은 30일까지만 있는 것으로 계산, 1년에 3개의 달, 100개의 일 이 있는 새로운 달력 개념 등등) 그렇기에, long을 사용한 풀이를 알아두면 좋을 것이다.
https://coding-factory.tistory.com/669
2) 시간이 친절하게 각각 int 값으로 주어지는 경우도 있지만, string에 "2022:02:11:..." 이런식으로 주어진 경우도 있다.
이럴 경우, c++에선 string의 split 함수를 직접 구현해서 ':' 기준으로 잘라서 저장해야한다.
아래는, 내가 string -> vector<int> ( 초, 분, 시, 일, 월, 년) <-> longlong(전부 '초'로 전환) 의 변환함수를 구현한 예시이다.
#include<iostream>
#include<sstream>
#include<vector>
#include <algorithm>
using namespace std;
//자기 이전의 단위로 해당 단위를 구성하기 위해 필요한 양을 정의
#define year 12 //12달 = 1년
#define mon 30
#define day 24
#define hour 60 //60분 = 1시간
#define min 60 //60초=1분
#define sec 1
long long year_sec = sec * min * day * hour * mon*year;
vector<int> time_unit = { sec,min,hour,day,mon,year };
vector<int> string_to_time(string str) {
stringstream ss(str);
vector<int> v;
while (getline(ss, str, ':')) {
v.push_back(stoi(str));
}
reverse(v.begin(), v.end());
return v;
}
long long time_to_long(vector<int> time) {
int h, m, s;
long long tmp = 1;
long long sum = 0;
for (int i = 0; i < time.size(); i++) {
tmp *= time_unit[i];
sum += time[i] * (tmp);
}
return sum;
}
vector<int> long_to_time(long long t) {
long long to_sec = year_sec;
vector<int> time;
for (int i = time_unit.size()-1; i >=0; i--) {
long long now = t / to_sec;
time.push_back(now);
t %= to_sec;
to_sec /= time_unit[i];
}
return time;
}
int main() {
int n, k;
long long total = 0;
vector<int> answer;
string st_time = "2022:11:29:23:59:59";
vector<string> times = { "01:01:01:01","02:23:01:01" };
vector<int> vec_stt = string_to_time(st_time);
cout << "================ string_to_time" << endl;
for (auto a : vec_stt) {
cout << a << " ";
}
cout << endl;
long long long_stt = time_to_long(vec_stt);
cout << "================ time_to_long" << endl;
cout << long_stt;
cout << endl;
vector<int> vv_stt = long_to_time(long_stt);
cout << "================ long_to_time" << endl;
for (auto a : vv_stt) {
cout << a << " ";
}
cout << endl;
string day1 = "2022:11:29:23:59:59", addTime = "0:0:0:0:0:1";
cout << day1 << " + " << addTime << " =?" << endl;
long long timeAdded = time_to_long(string_to_time(day1)) + time_to_long(string_to_time(addTime));
vector<int> ans = long_to_time(timeAdded);
for (auto a : ans) {//초, 분, 시, 일, 월, 년 순 출력
cout << a << " ";
}
}
3) 날짜 계산: Long으로 변환 x
더한 뒤, 작은 단위부터 계산하면서 최소 범위 초과시 증가시켜나가면 된다.
#include<iostream>
#include<sstream>
#include<vector>
#include <algorithm>
using namespace std;
vector<int> add_date(vector<int> a, vector<int> b) {
vector<int> ans;
int add = 0;
int sec = a[0] + b[0];
if (sec >= 60) {
sec -= 60;
add = 1;
}
ans.push_back(sec);
int min = a[1] + b[1]+add;
add = 0;
if (min >= 60) {
min -= 60;
add = 1;
}
ans.push_back(min);
int hour = a[2] + b[2] + add;
add = 0;
if (hour >= 24) {
hour -= 24;//
add = 1;
}
ans.push_back(hour);
int day = a[3] + b[3] + add;
add = 0;
if (day >= 31) {
day -= 30;// 1일부터 시작. 따라서 빼고나서 1일부터... 31-30 ==1
add = 1;
}
ans.push_back(day);
int mon = a[4] + b[4] + add;
add = 0;
if (mon >= 13) {
mon -= 12; //13-12 ==1 월 부터
add = 1;
}
ans.push_back(mon);
int year = a[5] + b[5] + add;
ans.push_back(year);
add = 0;
return ans;
}
int main() {
int n, k;
long long total = 0;
vector<int> answer;
string day1 = "2022:12:30:23:59:59", addTime = "0:0:0:0:0:1";
vector<int> ans = add_date(string_to_time(day1), string_to_time(addTime));
for (auto a : ans) {//초, 분, 시, 일, 월, 년 순 출력
cout << a << " ";
}
}
'코딩테스트' 카테고리의 다른 글
순열, 조합 c++ [재귀를 이용한 풀이] (0) | 2023.07.27 |
---|---|
[삼성 sw 역량 테스트 A형 샘플 문제] 프로세서 연결하기 c++ (0) | 2023.07.26 |
대여 기록이 존재하는 자동차 리스트 구하기 (1) | 2023.07.20 |
sql 사용 완전 공략 [mysql] (0) | 2023.07.20 |
[프로그래머스] 특정 기간 동안 대여 가능한 차들의 비용 구하기 (mysql) (0) | 2023.07.20 |