BZOJ 3109: [cqoi2013]新数独
3109: [cqoi2013]新数独
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 730 Solved: 435
[Submit][Status][Discuss]
Description
Input
输入一共15行,包含一个新数独的实例。第奇数行包含左右方向的符号(<和>),第偶数行包含上下方向的符号(^和v)。
Output
输出包含9行,每行9个1~9的数字,以单个空格隔开。输入保证解惟一。
Sample Input
< > > < > <
v v ^ ^ v v ^ ^ ^
< < > < > <
^ ^ ^ v ^ ^ ^ v v
< < < < > >
> < > > > >
v ^ ^ ^ ^ v v v ^
> > > > < >
v v ^ v ^ v ^ v ^
> < < > > >
< < < < > <
v ^ v v v v ^ ^ v
< > > < < >
^ v v v ^ v ^ v v
< > < > < >
v v ^ ^ v v ^ ^ ^
< < > < > <
^ ^ ^ v ^ ^ ^ v v
< < < < > >
> < > > > >
v ^ ^ ^ ^ v v v ^
> > > > < >
v v ^ v ^ v ^ v ^
> < < > > >
< < < < > <
v ^ v v v v ^ ^ v
< > > < < >
^ v v v ^ v ^ v v
< > < > < >
Sample Output
4 9 1 7 3 6 5 2 8
2 3 7 8 1 5 6 4 9
5 6 8 2 4 9 7 3 1
9 1 3 6 5 4 8 7 2
8 5 4 9 7 2 1 6 3
7 2 6 3 8 1 9 5 4
3 4 9 5 6 8 2 1 7
1 8 5 4 2 7 3 9 6
6 7 2 1 9 3 4 8 5
2 3 7 8 1 5 6 4 9
5 6 8 2 4 9 7 3 1
9 1 3 6 5 4 8 7 2
8 5 4 9 7 2 1 6 3
7 2 6 3 8 1 9 5 4
3 4 9 5 6 8 2 1 7
1 8 5 4 2 7 3 9 6
6 7 2 1 9 3 4 8 5
HINT
Source
题解:暴力搜索+剪枝;
整理一下判断条件:
1.这一行是否有重复的数
2.这一列是否有重复的数
3.这一个小九宫格中是否有重复的数
4.是否符合大于小于的条件
现在我分别用 h[i][j] ,l[i][j] ,g[i][j] 来表示第i行,第i列,第i个小九宫格中数字j是否重复。还有一个大于小于号的问题后面再说,让我们先来看一下读入。
输入格式: 一共15行,包含一个新数独的实例。第奇数行包含左右方向的符号(<和>),第偶数行包含上下方向的符号(^和v)
说是奇数行包含左右方向的符号,偶数行包含上下方向的符号,其实如果你仔细的看一下题目或者样例输入的话,应该不难发现输入格式的描述略有问题,有的行与输入描述是相反的。。。(如果已经改过来了就当我没说)
其实可以这样看:输入是有15行的,你可以把这15行分成3组,每组5行,这样描述就对了,每一组的奇数行和偶数行按描述进行读入即可。
读入符号之后,先看这个符号属于哪一个小九宫格(因为不同小九宫格的符号是不相关的),然后就要用到下面这个数组了:
f[i][x][y]
它表示第i个小九宫格中第x个数和第y个数是否有大小关系。
读入的时候如果是">"或者"v"就在相应的位置保存1,如果是"<"或"^"就保存2。
那么这样一来符号的问题就不是问题了,在选数的时候多加一个循环判断一下这个数周围的大小关系是否合法不就行了?
参考代码为:
1 #include<iostream> 2 #include<bits/stdc++.h> 3 using namespace std; 4 int a[10][10],h[10][10],l[10][10],g[10][10],m,n,c,f[10][10][10]; 5 void dfs(int x,int y) 6 { 7 if(x==9&&y==10) 8 { 9 for(int i=1;i<=9;++i) 10 { 11 for(int j=1;j<=9;++j) printf("%d ",a[i][j]); 12 cout<<endl; 13 } 14 return; 15 } 16 if(y==10) x=x+1,y=1; 17 for(int i=1;i<=9;++i) 18 { 19 bool bl=0; 20 int g1=((x-1)/3)*3,g2=(y-1)/3,g3=g1+g2; 21 if(g[g3][i]==1||h[x][i]==1||l[y][i]==1) continue; 22 for(int j=1;j<=9;++j) 23 { 24 int ii=(x-1)%3*3+(y-1)%3+1; 25 if(f[g3][ii][j]==1) 26 { 27 int xj=g3/3*3+(j-1)/3+1,yj=g3%3*3+(j-1)%3+1; 28 if(a[xj][yj]!=0) 29 if(i<a[xj][yj]) 30 { 31 bl=1; 32 break; 33 } 34 } 35 if(f[g3][ii][j]==2) 36 { 37 int xj=g3/3*3+(j-1)/3+1,yj=g3%3*3+(j-1)%3+1; 38 if(a[xj][yj]!=0) 39 if(i>a[xj][yj]) 40 { 41 bl=1; 42 break; 43 } 44 } 45 } 46 if(bl==1) continue; 47 g[g3][i]=1;h[x][i]=1;l[y][i]=1; 48 a[x][y]=i; 49 dfs(x,y+1); 50 a[x][y]=0; 51 g[g3][i]=0;h[x][i]=0;l[y][i]=0; 52 } 53 54 } 55 int main() 56 { 57 int ci=0; 58 char s; 59 for(int i=1;i<=3;++i) 60 { 61 for(int k=1;k<=5;++k) 62 { 63 if(k%2==1) 64 { 65 for(int j=1;j<=6;++j) 66 { 67 int q1=(i-1)*3,q2=(j-1)/2,q3=q1+q2; 68 cin>>s; 69 if(s=='>') 70 { 71 int qq=(k-1)/2*3+(j-1)%2+1; 72 f[q3][qq][qq+1]=1; 73 f[q3][qq+1][qq]=2; 74 } 75 else 76 { 77 int qq=(k-1)/2*3+(j-1)%2+1; 78 f[q3][qq][qq+1]=2; 79 f[q3][qq+1][qq]=1; 80 } 81 } 82 } 83 else 84 { 85 for(int j=1;j<=9;++j) 86 { 87 int q1=(i-1)*3,q2=(j-1)/3,q3=q1+q2; 88 cin>>s; 89 if(s=='v') 90 { 91 int qq=(k-1)/2*3+(j-1)%3+1; 92 f[q3][qq][qq+3]=1; 93 f[q3][qq+3][qq]=2; 94 } 95 else 96 { 97 int qq=(k-1)/2*3+(j-1)%3+1; 98 f[q3][qq][qq+3]=2; 99 f[q3][qq+3][qq]=1; 100 } 101 } 102 } 103 } 104 } 105 dfs(1,1); 106 return 0; 107 }