求四阶的素数幻方。即在一个4x4的矩阵中每一个格填入一个数字,使每一行、每一列和两条对角线上的4个数字所组成的四位数,均为可逆素数。
#include <stdio.h>
#include<math.h>
int number[210][5];
int select[110];
int array[4][5];
int count;
int selecount;
int larray[2][200];
int lcount[2];
int num(int number) //素数可逆?
{
int j;
if(!fflag(number))
return 0;
for(j = 0;number > 0;number /= 10)
j = j*10 + number%10;
if(!fflag(j))
return 0;
return 1;
}
int fflag(int n) //素数?
{
int i;
if(n == 0 || n == 1)
return 0;
for(i = 2; i < n/2; i++)
{
if(n%i == 0)
return 0;
}
if(i >= n/2)
return 1;
}
void process(int i)
{
int j,num;
num = number[i][0];
for(j = 4; j >= 1; j--,num /= 10)
number[i][j] = num%10;
}
void copy_num(int i)
{
int j;
for(j = 1; j <= 4; j++)
array[i][j] = number[array[i][0]][j];
}
int comp_num(int n)
{
static int ii;
static int jj;
int i,num,k,*p;
int *pcount;
switch(n)
{
case 2 :
pcount=&lcount[0];
p=ⅈ
break;
case 3 :
pcount=&lcount[1];
p=&jj;
break;
default:
return 0;
}
for(i = 1; i <= 4; i++)
{
for(num = 0,k = 0; k < n; k++)
num = num*10 + array[k][i];
if(num <= larray[n-2][*p])
for(; *p >= 0 && num < larray[n-2][*p]; (*p)--)
{
;
}
else
for( ; *p < *pcount && num > larray[n-2][*p]; (*p)++)
{
;
}
if(*p < 0 || *p >= *pcount)
{
*p = 0;
return 0;
}
if(num != larray[n-2][*p])
return 0;
}
return 1;
}
int find1(int i)
{
int num,j;
for(num = 0,j=0;j < 4; j++)
num = num*10 + array[j][i];
return ( find0(num) );
}
int find2(void)
{
int num1,num2,i,j;
for(num1 = 0,j =0; j < 4; j++)
num1 = num1*10 + array[j][j+1];
for(num2 = 0,j = 0,i = 4; j < 4; j++,i--)
num2 = num2*10 + array[j][i];
if(find0(num1))
return (find0(num2));
else
return 0;
}
int find0(int num)
{
static int j;
if(num <= number[j][0])
for(; j >= 0 && num < number[j][0]; j--)
{
;
}
else
for(; j < count && num > number[j][0]; j++)
{
;
}
if(j < 0 || j >= count)
{
j=0;
return 0;
}
if(num == number[j][0])
return 1;
else
return 0;
}
void p_array()
{
int i,j;
for(i = 0; i < 4; i++)
{
for(j = 1; j <= 4; j++)
printf("%6d",array[i][j]);
printf("\n");
}
}
int main()
{
int i,k,flag,cc=0,i1,i4;
printf("There are magic squares with invertable primes as follow:\n");
for(i = 1001; i < 9999; i += 2)
{
k = i/1000;
if(k%2 != 0 && k != 5 && num(i))
{
number[count][0] = i;
process(count++);
if( number[count-1][2]%2 != 0 &&
number[count-1][3]%2 != 0 &&
number[count-1][2] != 5 &&
number[count-1][3] != 5)
select[selecount++] = count-1;
}
}
larray[0][lcount[0]++] = number[0][0]/100;
larray[1][lcount[1]++] = number[0][0]/10;
for(i = 1; i < count; i++)
{
if(larray[0][lcount[0]-1] != number[i][0]/100)
larray[0][lcount[0]++] = number[i][0]/100;
if(larray[1][lcount[1]-1] != number[i][0]/10)
larray[1][lcount[1]++] = number[i][0]/10;
}
for(i1 = 0; i1 < selecount; i1++)
{
array[0][0] = select[i1];
copy_num(0);
for(array[1][0] = 0; array[1][0] < count; array[1][0]++)
{
copy_num(1);
if(!comp_num(2))
continue;
for(array[2][0] = 0;array[2][0] < count;array[2][0]++)
{
copy_num(2);
if(!comp_num(3))
continue;
for(i4 = 0; i4 < selecount; i4++)
{
array[3][0] = select[i4];
copy_num(3);
for(flag = 1,i = 1;flag && i <= 4;i++)
if(!find1(i))
flag = 0;
if(flag && find2())
{
printf("No.%d\n",++cc);
p_array();
}
}
}
}
}
return 0;
}
敲以上代码花了很长时间,错误就一两个。
今天主要学习结构体和链表,共同体等内容,还是较容易掌握的。