计蒜客:金字塔数独(java)

运用dfs算法

蒜头君天资聪颖,酷爱数学,尤其擅长做数独游戏。不过普通的数独游戏已经满足不了蒜头君了,于是他发明了一种“金字塔数独”:

下图即为金字塔数独。和普通数独一样,在9×9的大九宫格中有9个3×3的小九宫格(用粗黑色线隔开的)。要求每个格子上都有一个19的数字,每个数字在每个小九宫格内不能重复出现,每个数字在每行、每列也不能重复出现。

但金字塔数独的每一个格子都有一个分值,类似金字塔的俯视图。如图所示,白色格子为6分,蓝色格子为7分,绿色格子为8分,紫色格子为9分,红色格子为10分。颜色相同的格子分值一样,离中心越近则分值越高。

 

金字塔数独的总分等于每个格子上的数字和对应的分值乘积之和。现在蒜头君给定金字塔数独的若干数字,请问如何填写,可以使得金字塔数独的总分最高。

输入格式

输入一共9行。每行输入9个整数(每个数都在0—9的范围内),每两个整数之间用一个空格隔开,“0”表示该格子为空。

输出格式

输出为一行,输出一个整数,代表金字塔数独的最高总分。如果数独无解,则输出1

样例输入

0 0 0 0 0 0 0 0 0

0 0 3 0 0 0 9 0 0

7 9 0 0 0 2 0 1 3

0 0 9 1 5 0 0 0 0

0 7 4 0 2 6 1 3 9

0 0 6 0 0 0 0 0 0

6 0 0 0 0 7 0 0 0

3 1 0 4 0 5 7 9 6

0 0 7 0 0 1 0 4 0

样例输出

2864

public class Main {
	static int [][]p=new int[10][10];
	static int [][]l=new int[10][10];//行标记
	static int [][]c=new int[10][10];//列标记
	static int [][]pi=new int[10][10];//块标记
	static int maxn;
	static int sum1;
public static int score(int i,int j)
	{
		if(i==1||j==1||i==9||j==9)return 6;
		if(i==2||j==2||i==8||j==8)return 7;
		if(i==3||j==3||i==7||j==7)return 8;
		if(i==4||j==4||i==6||j==6)return 9;
		return 10;
	}
static void dfs(int step,int sum)
{
	if(step==sum1)
	{
		maxn=max(maxn,sum);
		return ;
	}

		for(int i=9;i>=1;i--)
		{
			for(int j=9;j>=1;j--)
			{
				if(p[i][j]!=0)
				continue;
				for(int k=1;k<=9;k++)
				{
					int x,y,z ;
					x=(i-1)/3;
					y=(j-1)/3;
					z=x*3+y+1;
		
					if(l[i][k]==0&&c[j][k]==0&&pi[z][k]==0)
					{
						p[i][j]=k;
						l[i][k]=1;
						c[j][k]=1;
						pi[z][k]=1;
						step++;
						dfs(step,sum+score(i,j)*k);
						p[i][j]=0;
						step--;
						l[i][k]=0;
						c[j][k]=0;
						pi[z][k]=0;
					}
				}
				return ;
			}
		}
		return ;
}


private static int max(int maxn2, int sum) {
	if (sum<=maxn2) {
		return maxn2;
	}
	else {
		return sum;
	}
}
public static void main(String[] args) {
	int t,t1,t2;
	int num=0;
	int s1=0;
	for(int i=1;i<=9;i++)
	{
		for(int j=1;j<=9;j++)
		{
			System.out.println(p[i][j]);
			if(p[i][j]==0)
			{
				t1=(i-1)/3;
				t2=(j-1)/3;
				t=t1*3+t2+1;
				l[i][p[i][j]]=1;
				c[j][p[i][j]]=1;
				pi[t][p[i][j]]=1;
				s1++;
				num+=score(i,j)*p[i][j];
			}
		}
	}
	sum1=81-s1;

	dfs(0,num);
	if(maxn==0)
	{System.out.println("");}
	else
		{System.out.println(maxn);}

}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光搬运工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值