在一个3*3方格中填入数字1~n(N>10)内的某9个互不相同的整数,使所有相邻两个方格的两个整数之和为质数,试求出满足这个要求的所有填法!

爱此清夜雨 2008-12-12 01:26:19
如题!
希望大家给我一个思路
最好是用c#来帮我解答这道问题!
...全文
1729 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
wwwwdddmm 2009-03-06
  • 打赏
  • 举报
回复
#include "stdio.h"
#define N 11/*设定可填入的整数个数*/
int pos;/*标示方格的序号*/
int a[9];/*用于存储方格所填入的整数*/
int b[N];/*用于存储整数是否填入方格的标志,若填入则该标志为0*/
int checkmatrix[][3]={{-1},{0,-1},{1,-1},{0,-1},{1,3,-1},{2,4,-1},{3,-1},{4,6,-1},{5,7,-1}};
/*存储需要需要检查合理性的相邻方格的序号,-1拦截以结束检查*/
void write(int a[])/*打印一组解*/
{ int i,j;

printf("------------------\n");
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
printf("%3d",a[3*i+j]);
}
printf("\n");
}
printf("------------------\n");
}
int isprime(int m)/*判断一个数是否是素数*/
{
int i;
int primes[]={2,3,5,7,11,17,19,23,29,-1};
if(m==1||m%2==0) return 0; /*若为1或偶数则排除*/
for(i=0;primes[i]>0;i++)
if(m==primes[i]) return 1; /*若为列表中素数则确认*/
for(i=3;i*i<=m;i+=2)if(m%i==0)return 0; /*寻找m的因数,若有因数则排除*/
return 1;
}
int selectnum(int start)/*从小到大查找还未填入方格中的整数,若无返回0*/
{
int j;
for(j=start;j<N;j++)if(b[j])return j;
return 0;
}
int check(int pos)/*检查填入POS位置的整数是否合理*/
{int i,j;
for(i=0;(j=checkmatrix[pos][i])>=0;i++)/*查找检验合理性数组中对应行存放的相邻方格的序号*/
if(!isprime(a[pos]+a[j]))return 0;/*检验相邻方格的序号是否为素数*/
return 1;
}
int extend(int pos)/*为下一个方格找一个尚未使用过的整数*/
{a[++pos]=selectnum(1);
b[a[pos]]=0;/*置标志位为0,该数已填入*/
return pos;
}
int change(int pos)/*调整当前方格填入的整数,使其合理,若找不到则回溯*/
{
int j;
while(pos>=0 && (j=selectnum(a[pos]+1))==0)b[a[pos--]]=1;/*若找不到则后退到前一方格,并清除当前方格整数的填入标志*/
if(pos<0)return -1;/*若第一个方格也找不到则返回-1,表明已回溯完毕*/
b[a[pos]]=1;/*恢复已填入但不合理的整数*/
a[pos]=j;/*填入下一个试探的数*/
b[j]=0;/*置该试探数的填入标志为0,表明填入*/
return pos;/*返回当前方格的序号*/
}
void find()/*寻找解主程序*/
{
int ok=1;
pos=0;a[pos]=1;b[a[pos]]=0;/*初始化*/
do{
if(ok)
if(pos==8)/*表明已找到一组解*/
{write(a);/*打印这组解*/
pos=change(pos);/*回溯,寻找另一组解*/
}
else pos=extend(pos);/*填下一个方格*/
else pos=change(pos);/*调整当前所填整数*/
ok=check(pos);/*判断当前方格所填数是否合理,合理则OK为1*/
}while(pos>=0);/*回溯完毕则循环结束,程序亦结束*/
}
main()
{
int i;
for(i=1;i<N;i++)
b[i]=1;/*所有整数的填入标志初始化*/
find();
}
bbbbbb888888 2008-12-12
  • 打赏
  • 举报
回复
mark
爱此清夜雨 2008-12-12
  • 打赏
  • 举报
回复
对角算是不相邻的!
应该填法有很多,应该是用循环做的,只是算法上还是想不清楚
止戈而立 2008-12-12
  • 打赏
  • 举报
回复
我首先想到的是把2放到中心。。加上2后是质数的数字很多,比如3、5、9、11等。。
止戈而立 2008-12-12
  • 打赏
  • 举报
回复
除非对角不算相邻,否则无法办到。。
经典填字游戏:在3*3个方格的方阵填入数字1到N(N>=10)内的某9个数字,每个方格一个整数,使得所有相邻两个方格内的两个整数之和为质数试求所有满足这个要求的各种数字填法。 //我们可以通过改变N的值来求不同数字范围的质数数组,如果超整型的范围,还需要改变数据类型。 //f[i]来记录数字i是否使用过, //T[i]用来记录下一个可以插在数字i后面的与其和为质数数字在F[i][]的位置。 //用F[i][j]来存储按数字从小到大的顺序得的与数字i和为质数的第j个数字, //例如:F[1][2]存储的是与数字1的和为质数的第二个数字,我们可以通过查询数组F[][]的第一行找第二个不为0 //值,然后将当前数组单元的列号存储到F[1][2],即F[1][2] = 4。 //算法思想是通过查询二维数组F[][],来确定下一个可以插入数组num[]的未使用过的数字,并记录该数字位于数组F[][]的位置, //以便回溯时寻找下一个符合要求数字。如果不存在这样的未使用的数字,则需要回溯到上一个已插入num[]的数字, //寻找下一个可以插在该数字后面的未使用过的数字进行插入,如果所有的数字都已经插入到num[], //如是则打印结果。当所有数字都已插入num[],开始 //进行回溯,重复上述操作,寻找其他符合要求的序列。 //这里面有一个关键在于处理位于num数组右下角四个格子的数时,不光需要判断与前一个数i的关系,还需要判断其头顶上的元素之和是否为素数。 //程序有一大段代码是处理i和j的。

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧