题目描述
质数方阵是一个 5 × 5 5×5 5×5的方阵,每行、每列、两条对角线上的数字可以看作是五位的素数。方格中的行按照从左到右的顺序组成一个素数,而列按照从上到下的顺序。两条对角线也是按照从左到右的顺序来组成。这些素数每一位上的数之和必须相等。 左上角的数字是预先定好的。 一个素数可能在方阵中重复多次。不计含有前导 0 0 0 的五位素数,如 00003 00003 00003 不是五位素数。
给出每一位上的数之和,以及左上角的数字,请输出方阵所有可能的填数方案。
如果不只有一个解,将它们全部输出(按照这 25 25 25 个数字组成的 25 25 25 位数的大小排序)。
输入格式
一行,包括两个被空格分开的整数:每一位上的数之和,以及左上角的数字。
输出格式
对于每一个找到的方案输出 5 5 5 行,每行 5 5 5 个字符,每行可以转化为一个 5 5 5 位的质数。在两组方案中间输出一个空行。如果没有解就单独输出一行 N O N E NONE NONE。
样例
样例输入
11 1
样例输出
11351
14033
30323
53201
13313
11351
33203
30323
14033
33311
13313
13043
32303
50231
13331
不怎么华丽的分割线
这道题是真的水难,暴力中还带着技巧。
总的来说,我的填写方法有点奇特
填写顺序騛常奇特
这样填是我随便想的,结果过了 (除先填左上到右下)
代码很丑,照着填写顺序思路,代码写的很通俗,只要你不被判断绕晕
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
int map[10][10];
}ans[110000];
bool cmp(node a,node b)
{
for(int i=0;i<=4;i++)for(int j=0;j<=4;j++)if (a.map[i][j]!=b.map[i][j])return a.map[i][j]<b.map[i][j];
}
int a[10][10],n,k;
bool b[110000];
void bt()
{
k++;for(int i=0;i<=4;i++)for(int j=0;j<=4;j++)ans[k].map[i][j]=a[i][j];
}
void dfs6()
{
for(int i=1;i<=9;i++)
if(a[0][0]+a[0][4]+i<=n&&a[1][1]+a[2][1]+a[3][1]+i<n&&n-i-a[1][1]-a[2][1]-a[3][1]<=9&&!b[i*10000+a[1][1]*1000+a[2][1]*100+a[3][1]*10+n-i-a[1][1]-a[2][1]-a[3][1]])
{
a[0][1]=i,a[4][1]=n-i-a[1][1]-a[2][1]-a[3][1];
for(int j=1;j<=9;j++)
if (a[0][0]+a[0][1]+j+a[0][4]<n&&n-j-a[1][2]-a[2][2]-a[3][2]<=9&&j+a[1][2]+a[2][2]+a[3][2]<n&&n-a[0][0]-a[0][1]-j-a