https://www.acmicpc.net/problem/1840
목적
스도쿠에 채워 넣을 번호가 81개의 줄에 걸쳐서 주어진다. 이때, 실수한 단계가 몇 번째인지 구하자.
접근법
1. 1~81번까지 올바른 입력인지 확인하기에는 시간제한에 걸린다. 이분탐색으로 확인할 단계 수를 줄이든, 틀린 위치부터 단계를 거슬러 올라가면서 구해야한다. 이분탐색은 72ms 정도가 걸린다. 후자의 방법은 0ms.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
#include<iostream>
#define f(i,l,r) for(int i=l;i<=r;++i)
#define set(i,j,k,l) used[0][i][k]=used[1][j][k]=used[2][3*((i-1)/3)+1+(j-1)/3][k]=l
using namespace std;
int t[82][3],s[10][10]={0,},used[3][10][10]={0,};
bool valid(int i,int j,int k){
return !(used[0][i][k]||used[1][j][k]||used[2][3*((i-1)/3)+1+(j-1)/3][k]);
}
bool fill(int i,int j){
if(i==9&&j==10) return true;
if(j==10)return fill(i+1,1);
if(s[i][j]!=0)return fill(i,j+1);
int ret=false;
f(k,1,9)if(valid(i,j,k)){
set(i,j,k,1);
ret=fill(i,j+1);
set(i,j,k,0);
if(ret)break;
}
return ret;
}
int main(){
f(i,1,81)cin>>t[i][0]>>t[i][1]>>t[i][2];
int a,b,c,j=0;
f(i,1,81){
a=t[i][0],b=t[i][1],c=t[i][2];
if(!valid(a,b,c)){
j=i;
while(!fill(1,1)){
--j;
a=t[j][0],b=t[j][1],c=t[j][2];
s[a][b]=0;
set(a,b,c,0);
}
break;
}
s[a][b]=c;
set(a,b,c,1);
}
cout<<(j==0?-1:j);
}
|
문제 설명과 코드에 대한 피드백은 언제나 환영합니다.
다양한 의견 댓글로 남겨주세요.
'Problem Solving > BOJ 백준' 카테고리의 다른 글
[ BOJ 백준 2606번 - 바이러스 ] 해설 및 코드 (0) | 2019.12.24 |
---|---|
[ BOJ 백준 3430번 - 용이 산다 ] 해설 및 코드 (0) | 2019.12.24 |
[ BOJ 백준 1300번 - K번째 수 ] 해설 및 코드 (0) | 2019.12.17 |
[ BOJ 백준 3020번 - 개똥벌레 ] 해설 및 코드 (0) | 2019.12.17 |
[ BOJ 백준 1939번 - 중량제한 ] 해설 및 코드 (0) | 2019.12.17 |