티스토리 뷰
[CF 1684C]Column Swapping - 1400
문제 설명
n개의 행과 m개의 열이 있으며 모든 값이 양의 정수인 격자가 주어진다. 이때 임의의 2개의 열의 위치(동일 위치끼리도 가능)를 서로 바꾸어 모든 행이 오름차순으로 정렬된 상태에 놓이게 만들 수 있는가? 만약 그렇다면 위치를 서로 교환할 2개의 열의 인덱스를 출력하고 그렇지 않으면 -1을 출력하라.
문제 풀이
- 문제를 단순화시켜서, 열이 1개짜리인 1xm 짜리 행렬(수열)이라고 가정해보자. 이 수열이 정확히 1번의 swap연산을 통해서 $a_i <= a_{i+1}$을 만족할 수 있는지 확인하는 방법을 찾은 후에 nxm 행렬로 확장하는 생각을 해보자.
- 열이 1개짜리인 수열에서 확인하는 방법은, a수열을 오름차순 정렬한 수열을 sorted배열이라고 했을 때 sorted[i]와 a[i]의 값이 다른 개수가 0개 또는 2개여야만 한다. 2개 이상이면 1번의 swap으로 고칠 수 없다는 뜻이다. 값이 다른 지점의 인덱스끼리 swap하고나면 반드시 오름차순 정렬을 만족할 것이다.
- 그럼 이제 이 방법을 n개의 열에 대해서 적용해보자. 이 문제에서는 어떤 column을 swap하면 해당 column에 매달려있는(마치 꼬치처럼)나머지 원소들도 줄줄이 swap될 것이다. 따라서 모든 열에서 (2번에서 설명했던) 값이 다른 지점의 인덱스는 모두 같아야만 한다.
- 다시말해, 나는 모든 row에서 sorted[i]와 a[i]의 값이 다른 지점의 인덱스가 모두 일관되는지만 확인해보면 된다.
소스 코드
int main(){
int t; scanf("%d",&t);
while(t--){
int n,m; scanf("%d %d",&n,&m);
vector<vector<int>> a(n,vector<int>(m));
for(int i=0 ; i<n ; i++)
for(int j=0 ; j<m ; j++)
scanf("%d",&a[i][j]);
vector<int> swapped;
for(int i=0 ; i<n ; i++){
vector<int> sorted = a[i];
sort(sorted.begin(),sorted.end());
for(int j=0 ; j<m ; j++){
if(a[i][j] != sorted[j]){
swapped.push_back(j);
}
}
if(swapped.size() > 0) break;
}
int imp = 0;
if(swapped.size() == 0){
imp = -1;
} else if(swapped.size() > 2){
imp = 1;
} else {
for(int i=0 ; i<n ; i++){
swap(a[i][swapped[0]],a[i][swapped[1]]);
for(int j=0 ; j<m-1 ; j++){
if(a[i][j] > a[i][j+1]){
imp = 1;
break;
}
}
}
}
if(imp == 1){
printf("-1\n");
} else if(imp == -1){
printf("1 1\n");
} else{
printf("%d %d\n",swapped[0]+1,swapped[1]+1);
}
}
}
'Problem Solving > Greedy' 카테고리의 다른 글
[CF 1667A] Make it Increasing (0) | 2022.06.15 |
---|---|
[CF 1136D] Nastya Is Buying Lunch (0) | 2019.07.06 |
[CF 898D] Alarm Clock (0) | 2019.06.28 |
[Codeforces 1153C] Serval and Parenthesis Sequence (0) | 2019.05.26 |
[Codeforces 950C] Zebras (0) | 2019.05.21 |
댓글