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)就已经算不出了,而且还不知道该怎么计算时间复杂度,这样的递归应该复杂度是很高的
可是通过剪枝应该优化了很多,不过不知道计算复杂度时侯要怎么考虑。

很大程度上还是根据提示写完的,代码能力太弱啦!
 1import java.util.*;
 2import java.util.regex.*;
 3import java.text.*;
 4import java.math.*;
 5import java.awt.geom.*;
 6
 7public 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}