http://acm.hdu.edu.cn/showproblem.php?pid=2780
分析:我去,注意可能输入的矩阵就不符合要求,以及最后一行不用再多输出空格了(各种处理,真的好讨厌)
回溯搜索
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int NM=9;
int vis[10],v1[10],v2[10],v3[10],k,flag,k1,k2;
char str[10][10];
struct Sudu{
int x,y;
}s[100];
bool judge(int x,char num)
{
int t1,t2,i,j;
memset(vis,0,sizeof(vis));
t1=s[x].x,t2=s[x].y;
for(i=0;i<NM;i++) //行
{
if(str[t1][i]==num)
return 0;
}
for(i=0;i<NM;i++) //列
{
if(str[i][t2]==num)
return 0;
}
t1=3*(s[x].x/3),t2=3*(s[x].y/3);
for(i=t1;i<t1+3;i++) //小矩阵
{
for(j=t2;j<t2+3;j++)
{
if(str[i][j]==num)
return 0;
}
}
return 1;
}
void DFS(int x)
{
int i,j;
if(x==k)
{
flag=1;
for(i=0;i<NM;i++)
{
for(j=0;j<NM;j++)
printf("%c",str[i][j]);
printf("\n");
}
}
if(flag) return;
for(i=1;i<=NM;i++) //
{
char num=i+'0';
if(judge(x,num))
{
str[s[x].x][s[x].y]=i+'0';
DFS(x+1);
str[s[x].x][s[x].y]='0';
}
}
}
void check()
{
int i,j,t1,t2,t;
for(i=0;i<NM;i++)
{
memset(v1,0,sizeof(v1));
memset(v2,0,sizeof(v2));
for(j=0;j<NM;j++)
{
t1=str[i][j]-'0';
t2=str[j][i]-'0';
if(t1==0) continue; //行
if(!v1[t1])
v1[t1]=1;
else
{flag=1;return;}
if(t2==0) continue; //列
if(!v2[t2])
v2[t2]=1;
else
{flag=1;return;}
}
}
for(i=0;i<NM;i+=3)
for(j=0;j<NM;j+=3)
{
memset(v3,0,sizeof(v3));
for(k1=i;k1<i+3;k1++)
for(k2=j;k2<j+3;k2++)
{
t=str[k1][k2]-'0';
if(t==0) continue;
if(!v3[t]) v3[t]=1;
else
{flag=1;return;}
}
}
}
int main()
{
int i,j,T;
scanf("%d",&T);
while(T--)
{
k=1;
for(i=0;i<NM;i++)
{
scanf("%s",str[i]);
for(j=0;j<NM;j++)
{
if(str[i][j]=='0')
{
s[k].x=i,s[k].y=j;
k++;
}
}
}
flag=0;
check(); //判断输入是否符合要求
if(flag)
{
printf("Could not complete this grid.\n");
if(T) printf("\n");
continue;
}
flag=0;
DFS(1);
if(!flag)
printf("Could not complete this grid.\n");
if(T) printf("\n");
}
return 0;
}

本文探讨了一个利用回溯搜索算法解决特定矩阵问题的方法。通过详细分析输入矩阵的约束条件,实现了一种有效的求解策略。该算法不仅处理了矩阵中元素的排列问题,还特别注意到了矩阵内部的行、列以及小矩阵内的元素限制,确保了最终解决方案的正确性和有效性。
1349

被折叠的 条评论
为什么被折叠?



