(百例编程)35.素数幻方(可深究)

题目:求四阶的素数幻方。即在一个4X4 的矩阵中,每一个格填 入一个数字,使每一行、每一列和两条对角线上的4 个数字所组成的四位数,均为可逆素数。

#include<iostream>
#include <vector>
using namespace std;
bool is_keni(int a);//判断可逆素数
bool is_sushu(int b);//判断素数
bool is_shaxuan(int c);//筛选函数
bool chaifen(int i,int j,int m,int n);//拆分函数
bool yanzheng(int t);//验证是不是可逆素数

int a[4][4];//存储题目要求的4*4矩阵
vector<int> su1;//存储千位为1的可逆素数
vector<int> su3;//存储千位为3的可逆素数
vector<int> su7;//存储千位为7的可逆素数
vector<int> su9;//存储千位为9的可逆素数
vector<int> s1;//存放可逆素数
vector<int> s2;//存放筛选后的可逆素数

int main(void)
{
   for (int i=1001;i!=9999;i+=2)
   {
	   if (is_keni(i))
	   {
		   s1.push_back(i);
		   if (is_shaxuan(i))
		   {
			   s2.push_back(i);
		   }
		   /*对可逆素数进行分段存*/
		   if (i>1000&&i<3000)
		   {
			   su1.push_back(i);
		   }
		   else if (i>3000&&i<7000)
		   {
			   su3.push_back(i);
		   }
		   else if (i>7000&&i<9000)
		   {
			   su7.push_back(i);
		   }
		   else
		   {
			   su9.push_back(i);
		   }

	   }	   
   }
for (int i=0;i<s2.size();++i)//矩阵第一行
  for (int j=0;j<s2.size();++j)//矩阵第四行
	  for(int m=0;m<s1.size();++m)//矩阵第二行
		  for(int n=0;n<s1.size();++n)//矩阵第三行
{
     chaifen(i,j,m,n); 
}
 
	return 0;
}

bool chaifen(int i,int j,int m,int n)//
{
    int t1=s2[i]/1000%10*1000+s1[m]/1000%10*100+s1[n]/1000%10*10+s2[j]/1000;
	if (yanzheng(t1))//第一列
	{
		t1=s2[i]/100%10*1000+s1[m]/100%10*100+s1[n]/100%10*10+s2[j]/100%10;
		if (yanzheng(t1))//第二列
		{
			t1=s2[i]/10%10*1000+s1[m]/10%10*100+s1[n]/10%10*10+s2[j]/10%10;
			if (yanzheng(t1))//第三列
			{
				t1=s2[i]%10*1000+s1[m]%10*100+s1[n]%10*10+s2[j]%10;
				if (yanzheng(t1))//第四列
				{
					t1=s2[i]/1000%10*1000+s1[m]/100%10*100+s1[n]/10%10*10+s2[j]%10;
					if (yanzheng(t1))//左对角线
					{
						t1=s2[i]%10*1000+s1[m]/10%10*100+s1[n]/100%10*10+s2[j]/1000%10;
							if (yanzheng(t1))//右对角线
							{
								/*把符合条件的数拆分*/
                                  for(int k=3,k1=1;s2[i]/k1>0;--k,k1*=10)
								  {
									  a[0][k]=s2[i]/k1%10;
								  }
								  for(int k=3,k1=1;s1[m]/k1>0;--k,k1*=10)
								  {
									  a[1][k]=s1[m]/k1%10;
								  }
								  for(int k=3,k1=1;s1[n]/k1>0;--k,k1*=10)
								  {
									  a[2][k]=s1[n]/k1%10;
								  }
								  for(int k=3,k1=1;s2[j]/k1>0;--k,k1*=10)
								  {
									  a[3][k]=s2[j]/k1%10;
								  }
								  for (int q=0;q!=4;++q)
									  for(int q1=0;q1!=4;++q1)
								  {
									  cout<<a[q][q1];
									  if (q1==3)
									  {
										  cout<<endl;
									  }
								  }
									  cout<<endl;
								  return true;
							}
					}
				}
			}
		}
	}
    
    return false;
    
}

bool yanzheng(int t)//判断所组成的数是不是为可逆素数
{
	int tem=t/1000;//取数的最高位来判断它是属于哪一段的可逆素数
    switch(tem)
	{
	case 1:
		{
			for (vector<int>::iterator ite=su1.begin();ite!=su1.end();++ite)
			{
				if ((*ite)==t)
				{
                       return true;
				}
			}
			return false;
			break;
		}

	case 3:
		{
			for (vector<int>::iterator ite=su3.begin();ite!=su3.end();++ite)
			{
				if ((*ite)==t)
				{
					return true;
				}
			}
			return false;
			break;
		}
	case 7:
		{
			for (vector<int>::iterator ite=su7.begin();ite!=su7.end();++ite)
			{
				if ((*ite)==t)
				{
					return true;
				}
			}
			return false;
			break;
		}
	case 9:
		{
			for (vector<int>::iterator ite=su9.begin();ite!=su9.end();++ite)
			{
				if ((*ite)==t)
				{
					return true;
				}
			}
			return false;
			break;
		}
	default:
		{
			return false;
			break;
		}		
	}

}

bool is_sushu(int b)//素数判断
{
	for (int i=2;i<=b/2;++i)
	{
		if (b%i==0)
		{
			return false;
			
		}
		if (i==b/2)
		{
			return true;
		}
	}
}

bool is_keni(int a)//可逆素数判断
{
	int a1[4],s=0;
	if (is_sushu(a))
	    {
             for (int j=0,k=1,t=1000;a/k>0;k*=10,t/=10,++j )//取位操作
                 {
                          a1[j]=a/k%10;
		                   s+=a1[j]*t;
                  }
	             if (is_sushu(s))
	              {
		              return true;
	               }
	          else
	             {
		             return false;
	             }
	   }
	else
	{
           return false;
	}
}

bool is_shaxuan(int c)//筛选函数
{
	int a1[4];
  for (int i=0,k=1;c/k>0;k*=10,++i)
  {
     a1[i]=c/k%10;
	 if (a1[i]%2==0||a1[i]==5)//第一行和最后一行的数不能为偶数和5
	 {
		 return false;
	 }
  }
   return true;
}


你可能感兴趣的:((百例编程)35.素数幻方(可深究))