四阶幻方/反幻方c++

1、四阶幻方

把1~16的数字填入4x4的方格中,使得行、列以及两个对角线的和都相等,满足这样的特征时称为:四阶幻方。
四阶幻方可能有很多方案。如果固定左上角为1,请计算一共有多少种方案。
比如:
1 2 15 16
12 14 3 5
13 7 10 4
8 11 6 9

以及:
1 12 13 8
2 14 7 11
15 3 10 6
16 5 4 9

就可以算为两种不同的方案。

#include <iostream>
#include <cstring>
using namespace std;
int a[17];
int b[17];
void dfs(int step);	
int sum=0;
int main()
{
	memset(b,1,sizeof(b));
	a[1]=1;
	b[1]=0;
	dfs(2);
	cout<<sum;
}
void dfs(int step)
{
	if(step==5)
	{
		int x=a[1]+a[2]+a[3]+a[4];
		if(x!=34)
			return;
	}
	else if(step==9)
	{
		int x=a[5]+a[6]+a[7]+a[8];
		if(x!=34)
			return;
	}
	else if(step==11)
	{
		int x=a[4]+a[7]+a[10];
		if(b[34-x]!=1)
			return;
		a[13]=34-x;
	}
	else if(step==12)
	{
		int x=a[1]+a[6]+a[11];
		if(b[34-x]!=1)
			return;
		a[16]=34-x;	
	}
	else if(step==13)
	{
		int x=a[9]+a[10]+a[11]+a[12];
		if(x!=34)
			return;	
	}
	else if(step==14)
	{
		int x=a[1]+a[5]+a[9]+a[13];
		if(x!=34)
			return;
	}
	else if(step==15)
	{
		int x=a[2]+a[6]+a[10]+a[14];
		if(x!=34)
			return;
	}
	else if(step==16)
	{
		int x=a[3]+a[7]+a[11]+a[15];
		if(x!=34)
			return;
	}
	else if(step==17)
	{
		int x=a[1]+a[6]+a[11]+a[16];
		int y=a[4]+a[7]+a[10]+a[13];
		if(x!=34)
			return;
		if(y!=34)
			return;	
		sum++;
		return;		
	}
	for(int i=2;i<=16;i++)
		if(b[i])
		{
			b[i]=0;
			a[step]=i;
			dfs(step+1);
			b[i]=1;	
		}
}

2、反幻方

我国古籍很早就记载着
2 9 4
7 5 3
6 1 8
这是一个三阶幻方。每行每列以及对角线上的数字相加都相等。
下面考虑一个相反的问题。
可不可以用 1~9 的数字填入九宫格,使得:每行每列每个对角线上的数字和都互不相等呢?
这应该能做到。
比如:
9 1 2
8 4 3
7 5 6
你的任务是搜索所有的三阶反幻方。并统计出一共有多少种。旋转或镜像算同一种。
比如:
		9 1 2 
		8 4 3
		7 5 6 

		7 8 9 
		5 4 1 
		6 3 2 

		2 1 9
		3 4 8
		6 5 7
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
int a[9]={1,2,3,4,5,6,7,8,9};
int main()
{
	int ans=0;
	do{
		int b[8];
		b[0]=a[0]+a[1]+a[2];
		b[1]=a[3]+a[4]+a[5];
		b[2]=a[6]+a[7]+a[8];
		b[3]=a[0]+a[3]+a[6];
		b[4]=a[1]+a[4]+a[7];
		b[5]=a[2]+a[5]+a[8];
		b[6]=a[0]+a[4]+a[8];
		b[7]=a[2]+a[4]+a[6];
		set < int > tem;
		for(int i=0;i<8;i++)
			tem.insert(b[i]);
		if(tem.size()==8)
			ans++;	
	}while(next_permutation(a,a+9));
	cout<<ans/8;
}

next_permutation(a,a+9)全排列函数

https://www.cnblogs.com/weixq351/p/9497108.html
#include <stdio.h>
#include <algorithm>
using namespace std;
int main(){
    int n;
    while(scanf("%d",&n)&&n){
        int a[1000];
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        sort(a,a+n);
        do{
            for(int i=0;i<n;i++)
                printf("%d ",a[i]);
            printf("\n");
        }while(next_permutation(a,a+n));
    }
    return 0;
}

例如输入

3

1 0 2

如果有sort()

输出为

0 1 2
0 2 1
1 0 2
1 2 0
2 0 1
2 1 0

若无

则输出为

1 0 2
1 2 0
2 0 1
2 1 0

发现函数next_permutation()是按照字典序产生排列的,并且是从数组中当前的字典序开始依次增大直至到最大字典序

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值