问题三十一:素数幻方 ,在一个4*4矩阵中,每一行,每一列,两条对角线上的四个数字组成的四位数均为可逆素数,求所有矩阵
/*
题目三十一:素数幻方 ,在一个4*4矩阵中,每一行,每一列,两条对角线上的四个数字组成的四位数均为可逆素数,求所有矩阵
分析:可逆素数可以判断,但是如果4*4方阵全部穷举,所需要的计算量极大
短时间内根本无法得出结果,需要化简问题 ,因为行数列数对角线均为可逆
素数,所以可以先求出所有的四位可逆素数进行穷举,计算量大大减少,因为是素数
所以每一行的末尾,每一列的末尾不可出现2的倍数和5倍数的数字,进一步缩减穷举
数据范围,在进行穷举则可得结果
1、第一行,第一列不能有零
2、最后一行,最后一列不能有2,5的倍数
3、四位可逆素数
4、测试前两行
5、测试前三行
6、输出结果
*/
#include<iostream>
#include<cmath>
#define MAX 500
using namespace std;
int all_sum;
int last_all_sum;
int first_all_sum;
int ke_ni(int n){//返回逆数
int i,num = n,total = 0;
int k,now = 1;
for(i = 0;i<4;i++){
for(k = 3;k>i;k--){
now *= 10;
}
total += num%10*now;
num /= 10;
now = 1;
}
return total;
}
int su_shu(int n){//判断是否为素数
int i,now;
if(n==1||n==0)return 0;
if(n==2)return 1;
now = (int)sqrt((double)n) + 1;
//now = n>>1;
for(i = 2;i<=now;i++){
if(n%i == 0)return 0;
}
return 1;
}
int get_n(int num,int i){//返回数n的第i位值
int last;
for(;i > 1;i--){
num /= 10;
}
last = num%10;
return last;
}
int last_row_len(int n){
int i;
for(i=1;i<=4;i++){
if(get_n(n,i)%2 == 0||get_n(n,i)%5 == 0){
return 0;
}
}
return 1;
}
int first_row_len(int n){
int i;
for(i=1;i<=4;i++){
if(get_n(n,i) == 0){
return 0;
}
}
return 1;
}
int yes(int *all,int *first,int *last,int a,int b,int c,int d){
int i;
int flag = 0;
for(i = 0;i<first_all_sum;i++){
if(first[i] == get_n(a,4)*1000+get_n(b,4)*100+get_n(c,4)*10+get_n(d,4)){
flag++;
break;
}
}
if(flag != 1)return 0;
for(i = 0;i<all_sum;i++){
if(all[i] == get_n(a,3)*1000+get_n(b,3)*100+get_n(c,3)*10+get_n(d,3)){
flag++;
break;
}
}
if(flag != 2)return 0;
for(i = 0;i<all_sum;i++){
if(all[i] == get_n(a,2)*1000+get_n(b,2)*100+get_n(c,2)*10+get_n(d,2)){
flag++;
break;
}
}
if(flag != 3)return 0;
for(i = 0;i<last_all_sum;i++){
if(last[i] == get_n(a,1)*1000+get_n(b,1)*100+get_n(c,1)*10+get_n(d,1)){
flag++;
break;
}
}
if(flag != 4)return 0;
for(i = 0;i<all_sum;i++){
if(all[i] == get_n(a,4)*1000+get_n(b,3)*100+get_n(c,2)*10+get_n(d,1)){
flag++;
break;
}
}
if(flag != 5)return 0;
for(i = 0;i<all_sum;i++){
if(all[i] == get_n(a,1)*1000+get_n(b,2)*100+get_n(c,3)*10+get_n(d,4)){
flag++;
break;
}
}
if(flag != 6)return 0;
return 1;
}
int yes_two(int *all,int *first,int *last,int a,int b){
int i;
int flag = 0;
for(i = 0;i<first_all_sum;i++){
if(get_n(first[i],4)*10+get_n(first[i],3) == get_n(a,4)*10+get_n(b,4)){
flag++;
break;
}
}
if(flag != 1)return 0;
for(i = 0;i<all_sum;i++){
if(get_n(all[i],4)*10+get_n(all[i],3) == get_n(a,3)*10+get_n(b,3)){
flag++;
break;
}
}
if(flag != 2)return 0;
for(i = 0;i<all_sum;i++){
if(get_n(all[i],4)*10+get_n(all[i],3) == get_n(a,2)*10+get_n(b,2)){
flag++;
break;
}
}
if(flag != 3)return 0;
for(i = 0;i<last_all_sum;i++){
if(get_n(last[i],4)*10+get_n(last[i],3) == get_n(a,1)*10+get_n(b,1)){
flag++;
break;
}
}
if(flag != 4)return 0;
for(i = 0;i<all_sum;i++){
if(get_n(all[i],4)*10+get_n(all[i],3) == get_n(a,4)*10+get_n(b,3)){
flag++;
break;
}
}
if(flag != 5)return 0;
for(i = 0;i<all_sum;i++){
if(get_n(all[i],4)*10+get_n(all[i],3) == get_n(a,1)*10+get_n(b,2)){
flag++;
break;
}
}
if(flag != 6)return 0;
return 1;
}
int yes_three(int *all,int *first,int *last,int a,int b,int c){
int i;
int flag = 0;
for(i = 0;i<first_all_sum;i++){
if(get_n(first[i],4)*100+get_n(first[i],3)*10+get_n(first[i],2) == get_n(a,4)*100+get_n(b,4)*10+get_n(c,4)){
flag++;
break;
}
}
if(flag != 1)return 0;
for(i = 0;i<all_sum;i++){
if(get_n(all[i],4)*100+get_n(all[i],3)*10+get_n(all[i],2) == get_n(a,3)*100+get_n(b,3)*10+get_n(c,3)){
flag++;
break;
}
}
if(flag != 2)return 0;
for(i = 0;i<all_sum;i++){
if(get_n(all[i],4)*100+get_n(all[i],3)*10+get_n(all[i],2) == get_n(a,2)*100+get_n(b,2)*10+get_n(c,2)){
flag++;
break;
}
}
if(flag != 3)return 0;
for(i = 0;i<last_all_sum;i++){
if(get_n(last[i],4)*100+get_n(last[i],3)*10+get_n(last[i],2) == get_n(a,1)*100+get_n(b,1)*10+get_n(c,1)){
flag++;
break;
}
}
if(flag != 4)return 0;
for(i = 0;i<all_sum;i++){
if(get_n(all[i],4)*100+get_n(all[i],3)*10+get_n(all[i],2) == get_n(a,4)*100+get_n(b,3)*10+get_n(c,2)){
flag++;
break;
}
}
if(flag != 5)return 0;
for(i = 0;i<all_sum;i++){
if(get_n(all[i],4)*100+get_n(all[i],3)*10+get_n(all[i],2) == get_n(a,1)*100+get_n(b,2)*10+get_n(c,3)){
flag++;
break;
}
}
if(flag != 6)return 0;
return 1;
}
int main(){
int i,count=0,j = 0;
int all_su[MAX];
for(i=1000;i<=9999;i++){
if(su_shu(i)==1&&su_shu(ke_ni(i))==1){
count++;
all_su[j] = i;
j++;
//cout<<i<<" ";
}
}
all_sum = j;
int last[MAX],k=0;
for(i=0;i<all_sum;i++){
if(last_row_len(all_su[i]) == 1){
last[k] = all_su[i];
//cout<<last[k]<<" ";
k++;
}
}
last_all_sum = k;
k = 0;
int first[MAX];
for(i=0;i<all_sum;i++){
if(first_row_len(all_su[i]) == 1){
first[k] = all_su[i];
//cout<<first[k]<<" ";
k++;
}
}
first_all_sum = k;
//方法一,速度有所提升,但仍然很慢
/*
int all[MAX][MAX];
int x;
int a=0;
for(i = 0;i<first_all_sum;i++){
for(j = 0;j<all_sum;j++){
for(k = 0;k<all_sum;k++){
for(x = 0;x<last_all_sum;x++){
if(yes(all_su,first,last,first[i],all_su[j],all_su[k],last[x])==1){
cout<<first[i]<<'\n'<<all_su[j]<<'\n'<<all_su[k]<<'\n'<<last[x]<<'\n'<<endl;
a++;
}
}
}
}
}
cout<<a<<endl;
*/
//方法二,速度极大提升
int x;
int a=0;
for(i = 0;i<first_all_sum;i++){
for(j = 0;j<all_sum;j++){
if(yes_two(all_su,first,last,first[i],all_su[j])==0)continue;
for(k = 0;k<all_sum;k++){
if(yes_three(all_su,first,last,first[i],all_su[j],all_su[k])==0)continue;
for(x = 0;x<last_all_sum;x++){
if(yes(all_su,first,last,first[i],all_su[j],all_su[k],last[x])==1){
cout<<first[i]<<'\n'<<all_su[j]<<'\n'<<all_su[k]<<'\n'<<last[x]<<'\n'<<endl;
a++;
}
}
}
}
}
cout<<a<<endl;
return 0;
}
这其中有不合适或者不正确的地方欢迎指正,我的QQ号码:2867221444(乔金明),谢谢,也可以相互交流下,备注信息随意,只要能看得出是开发者或者学习者即可。