这里用一个算法题进行比较。
原题是见http://acm.hdu.edu.cn/showproblem.php?pid=4090,登载在http://blog.csdn.net/woshi250hua/article/details/7997550
作者提供了一个比较快的答案。
我之前也尝试做了一个,没有用递归,但也没有用作者使用的格局保存的剪枝方案,比较慢,随后看了作者的方案后再整合进了一个基本等效的格局保存逻辑。
以下是作者的C++程序的基本等价的C#程序,
using System.Collections.Generic;
namespace HDU4090
{
internal class SolveGemAndPrince2
{
private const int Max = 10;
private struct Node
{
public int X;
public int Y;
}
private readonly Node[] _qu = new Node[Max*Max];
private readonly Dictionary<string, int> _hash = new Dictionary<string, int>();
private readonly int[,] _dir = new[,]
{
{1, 0}, {1, 1}, {1, -1}, {-1, 0}, {-1, -1}, {-1, 1}, {0, 1}, {0, -1}
};
private static void Change(int[,] mmap, ref int n, ref int m)
{
int i, j, tn = 0, tm = 0;
var k = new int[10];
for (j = 0; j < m; ++j)
{
k[j] = 0;
for (i = 0; i < n; ++i)
if (mmap[i, j] != 0) mmap[k[j]++, j] = mmap[i, j];
}
for (j = 0; j < m; ++j)
if (k[j] != 0)
{
for (i = 0; i < k[j]; ++i)
mmap[i, tm] = mmap[i, j];
for (i = k[j]; i < n; ++i)
mmap[i, tm] = 0;
tm++;
if (k[j] > tn) tn = k[j];
}
n = tn;
m = tm;
}
private int Ok(int[,] temp, int[,] vis, int i, int j, int n, int m)
{
var cnt = 0;
int head = 0, tail = 0;
Node cur;
cur.X = i;
cur.Y = j;
_qu[head++] = cur;
vis[cur.X,cur.Y] = 1;
while (tail < head)
{
cur = _qu[tail++];
cnt++;
int k;
for (k = 0; k < 8; ++k)
{
Node next;
next.X = cur.X + _dir[k,0];
next.Y = cur.Y + _dir[k,1];
if (next.X >= 0 && next.X < n
&& next.Y >= 0 && next.Y < m
&& vis[next.X,next.Y] == 0
&& temp[next.X,next.Y] == temp[i,j])
{
_qu[head++] = next;
vis[next.X,next.Y] = 1;
temp[next.X,next.Y] = 0;
}
}
}
temp[i,j] = 0;
return cnt >= 3 ? cnt : 0;
}
static string GetHash(int[,] temp,int n,int m)
{
var s = "";
for (var i = 0; i < n; ++i)
for (var j = 0; j < m; ++j)
s += temp[i,j] + '0';
return s;
}
static void Mem(int[,] temp, int[,] mmap, int n, int m)
{
for (var i = 0; i < Max; i++ )
for (var j = 0; j < Max; j++)
temp[i, j] = 0;
for (var i = 0; i < n; ++i)
for (var j = 0; j < m; ++j)
temp[i,j] = mmap[i,j];
}
int Dfs(int[,] mmap,int n,int m)
{
if (n*m < 3) return 0;
var temp = new int[Max,Max];
int i, j;
var vis = new int[Max,Max];
var cnt = 0;
for (i = 0; i < n; ++i)
for (j = 0; j < m; ++j)
if (vis[i,j]==0 && mmap[i,j]!=0)
{
Mem(temp, mmap, n, m);
var ans = Ok(temp, vis, i, j, n, m);
if (ans >= 3)
{
ans = ans*ans;
int tn = n, tm = m;
Change(temp, ref tn, ref tm);
var s = GetHash(temp, tn, tm);
#if true
if (!_hash.ContainsKey(s))
ans += Dfs(