AtCoder Beginner Contest 225 A부터 D까지 업솔빙
falconlee236
·2022. 6. 15. 22:50
AtCoder Beginner Contest 225 A부터 D까지 업솔빙
D번을 내가 왜 못풀었을까? 계속 강조하지만 문제를 너무 어렵게 생각하지 않는게 좋을 것 같다. 때로는 문제에서 하라는 대로 그대로 구현하는 능력도 중요하다는 것을 잊지말길. 하라는대로만 하고 그 다음 시간초과가 나면 새로운 알고리즘을 생각해보자.
문제 옆에 붙어있는 난이도는 Atcoder Problems 에서 추정한 것으로 작성했다는 것을 미리 알린다.
A - Distinct Strings (*12)
접기/펼치기
문제 설명
알파벳 소문자 3글자로만 이루어진 문자열 $S$가 주어진다. $S$를 나열할 때 얻을 수 있는 서로다른 문자열의 개수는 몇개일까?
문제 해설
모든 문자가 같으면 1, 모든 문자가 다르면 6, 그렇지 않으면 3을 출력.
안그러면 그냥 정렬하고 next_permutation을 사용하자.
정답 코드
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
string s; cin >> s;
if(s[0] == s[1] and s[1] == s[2]) cout << 1 << "\n";
else if(s[0] != s[1] and s[1] != s[2] and s[0] != s[2]) cout << 6 << "\n";
else cout << 3 << "\n";
return 0;
}
B - Star or Not (*62)
접기/펼치기
문제 설명
$N$개의 노드와 $N - 1$개의 간선으로 이루어진 트리가 주어진다. 이 트리가 별인지 아닌지 판단하라.
어떤 트리가 별이 되기 위해서는 한 노드가 다른 모든 노드와 간선으로 연결되어 있는 노드가 1개라도 있으면 별이다.
문제 해설
degree판단하는 것 처럼 각 정점의 degree를 모두 계산하고 정점의 degree가 n - 1인 정점이 하나라도 있으면 true를 출력한다.
정답 코드
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n; cin >> n;
vector<int> deg(n + 1);
for(int i = 0; i < n - 1; i++){
int a, b; cin >> a >> b;
deg[a]++;
deg[b]++;
}
for(int i = 1; i <= n; i++){
if(deg[i] == n - 1){
cout << "Yes";
return 0;
}
}
cout << "No";
return 0;
}
C - Calendar Validator (*326)
접기/펼치기
문제 설명
$10^{100} \times 7$ 크기의 행렬 $A$가 있다. 이 행렬의 $(i, j)$번째 칸에는 $(i - 1) \times 7 + j$ 의 값이 들어가 있다. $(1 \le i \le 10^100, 1 \le j \le 7)$
$N \times M$ 크기의 행렬 $B$가 주어진다. 이 행렬이 $A$의 일부분인지 판단하라.
문제 해설
$B$의 맨 왼쪽 위에 있는 원소가 있는 행과 열이 몇번째인지 먼저 구한다. 그리고 그 값부터 시작해서 순차적으로 값을 더하면서 그 위치에 아닌 값이 존재하면 false를 출력한다. 만약 해당 행의 최대값보다 큰 값이 그 행에 있는 것도 false로 한다.
정답 코드
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n, m; cin >> n >> m;
int a[n][m];
for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) cin >> a[i][j];
int r = (a[0][0] - 1) / 7, c = a[0][0] - (r * 7 + 1);
bool flag = true;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if((r + i) * 7 + c + j + 1 != a[i][j] or (r + i + 1) * 7 < a[i][j]) flag = false;
}
}
cout << (flag ? "Yes" : "No");
return 0;
}
D - Play Train (*778)
접기/펼치기
문제 설명
연주는 장난감 기차와 함께 기차를 연결하고 해체하는 게임을 하고 있다.
$N$개의 기차가 있으며 번호가 각각 $1, 2, ..., N$이 부여된다.
처음에는 모든 기차가 분리되어 있다.
$Q$개의 질의가 준비되어 있고, 질의를 주어진 순서대로 진행한다. 각 질의는 3가지 종류가 있다.
1 x y: 기차 $y$의 앞을 기차 $x$의 뒤에 붙인다.
- $x \neq y$ 이며,
- $x$의 뒤에는 아무것도 연결되어 있지 않으며,
- $y$의 앞에는 아무것도 연결되어 있지 않다.
2 x y: 기차 $y$의 앞과 기차 $x$의 뒤를 분리한다.
- $x \neq y$ 이며,
- $x와 $y$가 연결되어 있는 상태이다.
3 x: $x$와 연결되어 있는 기차의 맨 앞부터 뒤까지 연결되어있는 모든 기차 번호를 출력한다.
문제 해설
처음에는 뭐 링크드 리스트인지 뭔지 이거 생각해서 list자료구조 쓰려고 하다가 너무 삽질을 많이 하길래 그냥 해설을 보니까 나온대로 그대로 구현하면 끝나는 문제여서 허탈했다.
문제에서 필요한 값은 해당 기차의 앞번호와 해당 기차의 뒷 번호 기차가 무엇인지만 알면 된다. 그렇기 때문에 해당 기차의 앞 번호가 담겨있는 배열과 뒷 번호가 담겨있는 배열 두개를 만들고 각 종류의 쿼리를 진행하면 된다.
그후 3번 쿼리가 나오면 해당 기차의 맨 앞으로 이동한 후, 맨 뒤로 계속 꼬리를 물면서 값을 저장해나가면 답을 완성할 수 있다. 단순하게 쉬운 문제다.
정답 코드
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n, q; cin >> n >> q;
vector<int> front(n + 1, -1), rear(n + 1, -1);
while(q--){
int type, x, y; cin >> type;
if(type == 1){
cin >> x >> y;
front[y] = x;
rear[x] = y;
}else if(type == 2){
cin >> x >> y;
front[y] = -1;
rear[x] = -1;
}else{
cin >> x;
while(front[x] != -1) x = front[x];
vector<int> ans;
while(rear[x] != -1){
ans.push_back(x);
x = rear[x];
}
ans.push_back(x);
cout << ans.size() << " ";
for(auto x : ans) cout << x << " ";
cout << "\n";
}
}
return 0;
}
'알고리즘 > atcoder' 카테고리의 다른 글
AtCoder Beginner Contest 226 A부터 E까지 업솔빙 (0) | 2022.06.25 |
---|---|
AtCoder Beginner Contest 224 A부터 D까지 업솔빙 (0) | 2022.06.02 |
AtCoder Beginner Contest 223 A부터 D까지 업솔빙 (0) | 2022.05.28 |
AtCoder Beginner Contest 222 A부터 D까지 업솔빙 (0) | 2022.05.17 |
AtCoder Beginner Contest 221 A부터 D까지 업솔빙 (0) | 2022.05.08 |