我已经编写了一个代码来解决使用回溯的9x9数据,它以vector<vector<char> >
的形式输入并且有'。'如果缺少数字。当我运行代码时,我得到了一个TLE。我试过找到这个bug但却找不到。请指出错误。 next
函数返回要检查的下一个坐标。 safe
函数检查在某个位置分配号码是否安全。这是代码:
bool safe(vector<vector<char> > &A, int a, int b, int val)
{
int N = A.size();
//check horiz
int sum;
int i;
sum = 0;
for(i=0;i<N;i++)
{
if(A[a][i]=='.')
break;
else
sum+=A[a][i]-'0';
}
if(i==N && sum!=(N*(N+1)/2))
return 0;
//check vert
sum = 0;
for(int i=0;i<N;i++)
{
if(A[i][b]=='.')
break;
else
sum+=A[i][b]-'0';
}
if(i==N && sum!=(N*(N+1)/2))
return 0;
//check box
int x, y;
x = a%3;
y = b%3;
sum = 0;
for(int i=x*3;i<x*3 + 3;i++)
{
for(int j=y*3;j<y+3;j++)
{
if(A[i][j]=='.')
return 1;
else
sum+=A[i][j]-'0';
}
}
if(sum!=(N*(N+1)/2))
return 0;
}
pair<int, int> next(int a, int b)
{
int x, y;
x = a+1;
y = b;
if(x==9)
{
x=0;
y++;
}
pair<int, int> p = {x, y};
return p;
}
bool solve(vector<vector<char> > &A, vector<vector<bool> > B, int a, int b)
{
// cout<<a<<" "<<b<<endl;
if(b==A.size())
return 1;
pair<int, int> p;
if(B[a][b]==0)
{
p = next(a, b);
return solve(A, B, p.first, p.second);
}
else
{
for(int i=1;i<=9;i++)
{
if(safe(A, a, b ,i))
{
A[a][b] = i + '0';
p = next(a, b);
if(solve(A, B, p.first, p.second))
return 1;
}
}
A[a][b] = '.';
}
return 0;
}
void Solution::solveSudoku(vector<vector<char> > &A) {
vector<bool> tmp(A.size(), 0);
vector<vector<bool> > B(A.size(), tmp);
for(int i=0;i<A.size();i++)
{
for(int j=0;j<A.size();j++)
{
if(A[i][j]!='.')
{
B[i][j] = 1;
}
}
}
solve(A, B, 0, 0);
}
答案 0 :(得分:0)
代码中有两个主要错误:
addPotholeMarkers()
功能错误。
您需要确保行,列和框中没有两个数字相同。您正在计算每行,每列和每个值中的值的总和,如果预期总和则返回。这不起作用。我建议使用位域来跟踪使用的数字。
Ex :1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45 = 9 + 9 + 9 + 9 + 4 + 1 + 1 + 1 + 1 + 1
safe
没有使用传递给它的值safe
,这没关系,只是将其从参数列表中删除。
您应该使用val
时使用%
您正在重新定义变量名称,例如,循环中的变量/
与您在后续i
语句中使用的i
不同:< / p>
if
当递归调用无法找到解决方案时,您需要将for(int i=0;i<N;i++)
{
if(A[i][b]=='.')
break;
else
sum+=A[i][b]-'0';
}
if(i==N && sum!=(N*(N+1)/2))
重置为A[a][b]
。否则,您对'.'
的下一次调用将使用之前的状态。
safe
你真的不需要布尔的for(int i=1;i<=9;i++)
{
if(safe(A, a, b ,i))
{
A[a][b] = i + '0';
p = next(a, b);
if(solve(A, B, p.first, p.second))
return 1;
A[a][b] = '.'; //RESET BACK
}
}
向量。您可以将其删除,然后针对B
测试A[a][b]
。
我在代码中修复了这些错误,而且速度非常快。它在我的机器上在60毫秒内解决this puzzle。