https://www.acmicpc.net/problem/17140
침착하게 따라가면 풀 수 있는 문제이다.
문제에서 추출할 수 있는 정보는 다음과 같다.
행/열 연산이 거의 유사하기 때문에, 행 연산 기준으로 다뤄보자.
각 행마다 존재하는 숫자들(0 제외)을 숫자-등장횟수의 형태로 저장해두어야 하므로 map을 사용하였다. 이후 map을 vector로 바꾸고 위 언급한 조건에 따라 정렬한다.
bool cmp(pair<int, int> p1, pair<int, int> p2){
if(p1.second == p2.second) return p1.first < p2.first;
return p1.second < p2.second;
}
void R(){ // 행 연산
for(int i=1; i<=r; i++){
map<int, int> m; // 숫자-등장횟수
for(int j=1; j<=c; j++){
if(arr[i][j] != 0)
m[arr[i][j]]++;
}
vector<pair<int, int> > tmp(m.begin(), m.end());
sort(tmp.begin(), tmp.end(), cmp);
int s = 2 * tmp.size(); // 행의 크기 갱신 시도
c = max(c, s);
for(int j=1; j<=100; j++) // 0 채우기
arr[i][j] = 0;
for(int j=0; j<tmp.size(); j++){ // 결과 반영
arr[i][j*2 + 1] = tmp[j].first;
arr[i][(j+1)*2] = tmp[j].second;
}
}
}
가장 큰 행을 기준으로 모든 행의 크기가 변하기에, c값은 행 연산 시 증가하는 쪽으로 갱신된다. 큰 행이란 r이 아닌 c가 커진다는 것을 의미하기 때문이다. 즉 한 행이 오른쪽으로 길어지는 건 배열 상에서 c가 증가한다는 것이다.
매 행마다 0으로 채워지는 부분을 섬세하게 찾기 번거롭기 때문에, 특정 행을 새로운 연산으로 갱신하기 전 미리 0으로 채워두고, 연산의 결과를 반영한다.
int t = 0;
while(1){
t++;
if(r >= c){
R();
} else {
C();
}
if(arr[tr][tc] == k) break; // 성공
if(t >= 100){ // 100초가 지남
cout << -1;
return 0;
}
}
cout << t;
남은 조건을 반영하여, while문을 통해 시간을 카운트하면서 연산을 진행하면 된다.
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
using namespace std;
int tr, tc, k;
int r, c;
int arr[101][101];
bool cmp(pair<int, int> p1, pair<int, int> p2){
if(p1.second == p2.second) return p1.first < p2.first;
return p1.second < p2.second;
}
void R(){ // 행 연산
for(int i=1; i<=r; i++){
map<int, int> m; // 숫자-등장횟수
for(int j=1; j<=c; j++){
if(arr[i][j] != 0)
m[arr[i][j]]++;
}
vector<pair<int, int> > tmp(m.begin(), m.end());
sort(tmp.begin(), tmp.end(), cmp);
int s = 2 * tmp.size(); // 행의 길이 갱신 시도
c = max(c, s);
for(int j=1; j<=100; j++) // 0 채우기
arr[i][j] = 0;
for(int j=0; j<tmp.size(); j++){ // 결과 반영
arr[i][j*2 + 1] = tmp[j].first;
arr[i][(j+1)*2] = tmp[j].second;
}
}
}
void C(){ // 열 연산
for(int i=1; i<=c; i++){
map<int, int> m;
for(int j=1; j<=r; j++){
if(arr[j][i] != 0)
m[arr[j][i]]++;
}
vector<pair<int, int> > tmp(m.begin(), m.end());
sort(tmp.begin(), tmp.end(), cmp);
int s = 2 * tmp.size();
r = max(r, s);
for(int j=1; j<=100; j++)
arr[j][i] = 0;
for(int j=0; j<tmp.size(); j++){
arr[j*2 + 1][i] = tmp[j].first;
arr[(j+1) * 2][i] = tmp[j].second;
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
memset(arr, 0, sizeof(arr));
cin >> tr >> tc >> k;
r = 3;
c = 3;
for(int i=1; i<=r; i++){
for(int j=1; j<=c; j++){
cin >> arr[i][j];
}
}
if(arr[tr][tc] == k){ // 연산 진행할 필요없음
cout << 0;
return 0;
}
int t = 0;
while(1){
t++;
if(r >= c){
R();
} else {
C();
}
if(arr[tr][tc] == k) break; // 성공
if(t >= 100){ // 100초가 지남
cout << -1;
return 0;
}
}
cout << t;
return 0;
}