p1074靶形数独蒟蒻求助剪枝方法
  • 板块题目总版
  • 楼主KMSK
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/9/12 15:27
  • 上次更新2023/11/4 06:58:29
查看原帖
p1074靶形数独蒟蒻求助剪枝方法
472423
KMSK楼主2021/9/12 15:27

代码如下:用的深度优先搜索,救助剪枝思想或记忆化思路(个人感觉好像不能用记忆化搜索)

using namespace std;
int s[10][10];//分值 
int a[10][10];//区
int b[10][10];//行
int c[10][10];//列
int map[10][10];
int cc;
int ans=-1;
void inits()
{
	for(int i=1;i<=9;i++)
	s[1][i]=s[i][1]=s[9][i]=s[i][9]=6;
	for(int i=2;i<=8;i++)
	s[2][i]=s[i][2]=s[8][i]=s[i][8]=7;
	for(int i=3;i<=7;i++)
	s[3][i]=s[i][3]=s[7][i]=s[i][7]=8; 
	for(int i=4;i<=6;i++)
	s[4][i]=s[i][4]=s[6][i]=s[i][6]=9;
	s[5][5]=10;
}
void printff()
{
	for(int i=1;i<=9;i++)
		 {
		 	for(int j=1;j<=9;j++)
		 	{
		 		cout<<s[i][j]<<" ";
			 }
			 cout<<endl;
		 }
 }
 bool qu(int i,int j,int p)
 {
 	int t=(i-1)/3*3+(j-1)/3+1;
 	if(a[t][p])return true;
 	return false;
  } 
  bool hang(int i,int p)
  {
  	if(b[i][p])return true;
  	return false;
  }
  bool lie(int j,int p)
  {
  	if(c[j][p])return true;
  	return false;
  }
 void dfs(int i,int j,int sum)
 {
 	if(i==10&&j==1)
 	{
 		ans=max(ans,sum);
 		return;
	 }
	 if(map[i][j]==0)
	 {
	 	for(int k=1;k<=9;k++)
	 	{
	 		if(!qu(i,j,k)&&!hang(i,k)&&!lie(j,k))
	 		{
	 			map[i][j]=k;
	 			int t=(i-1)/3*3+(j-1)/3+1;//计算在哪个区
	 			a[t][k]=1;
	 			b[i][k]=1;
	 			c[j][k]=1;
	 			if(j<9)dfs(i,j+1,sum+k*s[i][j]);
	 			else dfs(i+1,1,sum+k*s[i][j]);
	 			map[i][j]=0;
	 			a[t][k]=0;
	 			b[i][k]=0;
	 			c[j][k]=0;
			 }
		 }
	 }
	 else 
	 {
	 	if(j<9)dfs(i,j+1,sum+s[i][j]*map[i][j]);
	 	else dfs(i+1,1,sum+s[i][j]*map[i][j]);
	 }
 }
int main()
{
		for(int i=1;i<=9;i++)
		for(int j=1;j<=9;j++)
		{
			cin>>cc;
			map[i][j]=cc;
			int t=(i-1)/3*3+(j-1)/3+1;
			a[t][cc]=1;
			b[i][cc]=1;
			c[j][cc]=1;
		 } 
		 //输出 
		 inits();
		 //printff();
		 dfs(1,1,0); 
		 cout<<ans;
		 return 0;
}
2021/9/12 15:27
加载中...