TopCoder SRM 392 Level2 1000
原题地址:http://www.topcoder.com/stat?c=problem_statement&pm=8561&rd=11126
两个整数n和d, 1<=n<=10, 1<=d<=n,求一个n*n方阵,每一行每一列都存在0~d的每个数,如果有多个矩阵,返回字母序最小的一个。
从头递归搜索,对每个位置从小遍历所有值,针对每个值做如下操作:
1.赋值为0
2.检查该行剩下的位置是否足够放下还没有出现的所有的数,若否返回第一步并且++;
3.检查该列剩下的位置是否足够放下还没有出现的所有的数,若否返回第一步并且++;
4.现在是一个可以考虑的值,首先是终结值,若该位置已经是矩阵右下角,则返回true,这是唯一返回true的起点
5.向后递归调用函数,调用下一个位置
6.如果返回值为true,则返回true,否则继续
7.返回false
总的来说,递归的顺序,1是遍历所有可能值,2,3是排除和剪枝,4是检测成功条件,5是递归调用,6,7是递归的结果
算法的复杂度较高,(15,15)就已经算不出了,而且还不知道该怎么计算时间复杂度,这样的递归应该复杂度是很高的
可是通过剪枝应该优化了很多,不过不知道计算复杂度时侯要怎么考虑。
很大程度上还是根据提示写完的,代码能力太弱啦!
1
import java.util.*;
2
import java.util.regex.*;
3
import java.text.*;
4
import java.math.*;
5
import java.awt.geom.*;
6
7
public class QuasiLatinSquares
8

{
9
int[][] ans;
10
int n;
11
int d;
12
13
public String[] makeSquare(int n, int d)
14
{
15
16
this.n = n;
17
this.d = d;
18
ans = new int[n][n];
19
backtrace(0,0);
20
21
//change the integer matrix to string array
22
String[] ret = new String[n];
23
for(int i = 0; i < n ; ++ i)
{
24
StringBuilder sb = new StringBuilder();
25
sb.append(ans[i][0]);
26
for(int j = 1; j < n ; ++ j)
{
27
sb.append(" ");
28
sb.append(ans[i][j]);
29
}
30
ret[i] = sb.toString();
31
}
32
return ret;
33
}
34
35
public boolean backtrace(int i, int j)
{
36
//have to check every value here
37
for(int v = 0; v < d; ++ v)
{
38
ans[i][j] = v;
39
40
//check whether still enough place for numbers that haven't appear
41
boolean[] row = new boolean[d];
42
boolean[] col = new boolean[d];
43
Arrays.fill(row, false);
44
Arrays.fill(col, false);
45
for(int rowidx = 0; rowidx <= i; ++ rowidx)
46
row[ans[rowidx][j]] = true;
47
for(int colidx = 0; colidx <= j; ++ colidx)
48
col[ans[i][colidx]] = true;
49
int rct = 0, cct = 0;
50
for(boolean b:row)
{
51
if(b == false) rct++;
52
}
53
for(boolean b:col)
{
54
if(b == false) cct++;
55
}
56
if(rct > n-1-i)
57
continue;
58
if(cct > n-1-j)
59
continue;
60
61
//if it's the last place, success!
62
if((i == n-1) && (j == n-1))
63
return true;
64
65
//recursively calculate latter numbers based on this value
66
boolean next;
67
if(j != n-1)
68
next = backtrace(i,j+1);
69
else
70
next = backtrace(i+1,0);
71
//if it has reached the end,it means this value has led to success, else it means the value has to increase
72
if(next == true)
73
return true;
74
75
}
76
//have checked every number but none matches, former numbers has to reconsider
77
return false;
78
}
79
}