코딩 테스트/알고리즘 풀이
[백준 - 2503] 숫자 야구
김띠띵
2022. 8. 31. 15:32
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
#define Strike first
#define Ball second
pii Check(string t, string ask)
{
int cnt_s = 0;
int cnt_b = 0;
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
if (t[i] == ask[j])
{
if (i == j) ++cnt_s;
if (i != j) ++cnt_b;
break;
}
}
}
return { cnt_s, cnt_b };
}
string ask[101];
pii sb[101];
int main()
{
ios::sync_with_stdio(0), cin.tie(0);
int answer = 0;
int n; cin >> n;
for (int i = 0; i < n; ++i)
{
cin >> ask[i] >> sb[i].Strike >> sb[i].Ball;
}
string temp;
pii tsb;
int i, j;
for (i = 123; i < 988; ++i)
{
temp = to_string(i);
if (temp[0] == temp[1] || temp[0] == temp[2] || temp[1] == temp[2]) continue;
if (temp[0] == '0' || temp[1] == '0' || temp[2] == '0') continue;
for (j = 0; j < n; ++j)
{
tsb = Check(temp, ask[j]);
if (sb[j] != tsb) break;
}
if (j == n) ++answer;
}
cout << answer;
return 0;
}
||사고 과정
이건 경우의수를 어떻게 for문으로 돌리는지 몰라서 이 부분만 다른 사람의 아이디어를 가져왔다.
내가 너무 어렵게 생각했었다.
123 ~ 987 까지의 순서도 상관없는 모든 경우의수를 어떻게 찾지? 하고 낑낑대며 고민했는데
그냥 123 부터 987까지 1씩 증가하면 되는거였다.....😑
정말 이거 알고 머리가 띵했다.... 바보인듯ㅜ
이 수를 어떻게 돌릴지 알고나서는 수월했다.
각 숫자가 모든 질문에 해당이 되면 카운트를 올린다.
즉 123 ~ 987 까지인 대략 900개와 최대 질문 개수인 100개,
이를 곱한 900 * 100 = 90'000 연산은 1초안에 충분했다.
심지어 가지치기로 122, 131, 424 처럼 중복이 들어간 수는 제외하고
특히 내가 마지막에 못찾았던 0이라는 예외도 처리해주면 더 줄어들것이다.
||사용 기법
- Brute Force
||풀면서 느낀 것
- continue, break
이거 두개를 자꾸 헷갈리게 사용해서 시간을 소모한적이 최근에 많고 이 문제에서도 그랬다.
주의할것
- 문자 비교
바보처럼 자꾸 정수랑 비교한다. 확실히 할것.
char c = '3';
//정수랑 비교 - X //문자랑 비교 - o
if(c == 3) if(c == '3')
||새로 알게 된것
- 123 ~ 987
이건 진짜 잘 배운것같다.
지금 아니였으면 또 어딘가에서 헤맸을것.
이 문제처럼 고정 자리인 부분집합에 완전 탐색이면 자주 사용할것 같다.
||다른 풀이
//1.
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
for(int k = 0; k < n; ++k)
{
//i가 백의자리숫자, j가 십의자리숫자, k가 일의자리숫자
}
}
}
//2.
for(int i = 123; i < 987; ++i)
{
int a = i / 100;
int b = i % 100 / 10;
int c = i % 10;
}
나는 문자로 변환해서 비교했지만
많은 사람들이 이렇게 정수로 비교하곤했다.