1312: [蓝桥杯2016决赛]反幻方 【简单 / 全排列 】

本文介绍了两种简化方法,一种使用`next_permutation`遍历数组并利用set去重,另一种直接通过组合计算全排列。主要讨论了如何利用集合自动去重特性快速判断特定数组是否构成八种翻转情况,以求得特定排列的总数并除以8。
摘要由CSDN通过智能技术生成

在这里插入图片描述
http://oj.ecustacm.cn/problem.php?id=1312

翻转的话有四种。镜像2种。4*2=8种 所以最后的结果除以8

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int a[]={1,2,3,4,5,6,7,8,9};
int main(void)
{
	int sum1,sum2,sum3;
	int sum4,sum5,sum6;
	int sum7,sum8;
	int sum=0;
	do
	{
		int b[30]={false};
		int n=0;
		sum1=a[0]+a[1]+a[2];
		sum2=a[3]+a[4]+a[5];
		sum3=a[6]+a[7]+a[8];
		
		sum4=a[0]+a[3]+a[6];
		sum5=a[1]+a[4]+a[7];
		sum6=a[2]+a[5]+a[8];
		
		sum7=a[0]+a[4]+a[8];
		sum8=a[2]+a[4]+a[6];
		
		b[sum1]=true;
		b[sum2]=true;
		b[sum3]=true;
		b[sum4]=true;
		b[sum5]=true;
		b[sum6]=true;
		b[sum7]=true;
		b[sum8]=true;
		for(int i=0;i<30;i++)
		{
			if(b[i]==true)
				n++; 
		}
		if(n==8)
		{
			sum++;
		}
	}while(next_permutation(a,a+9));
	printf("%d\n",sum/8);
	return 0;
}

进一步简单的写法: 用set自动去重的特性来判断

#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
int a[]={1,2,3,4,5,6,7,8,9};
set<int> se;
int sum1,sum2,sum3;
int sum4,sum5,sum6;
int sum7,sum8;
bool check()
{
	se.clear();
	sum1=a[0]+a[1]+a[2];
	sum2=a[3]+a[4]+a[5];
	sum3=a[6]+a[7]+a[8];
	se.insert(sum1);
	se.insert(sum2);
	se.insert(sum3);
	if(se.size()!=3)
		return false;
	sum4=a[0]+a[3]+a[6];
	sum5=a[1]+a[4]+a[7];
	sum6=a[2]+a[5]+a[8];
	se.insert(sum4);
	se.insert(sum5);
	se.insert(sum6);
	if(se.size()!=6)
		return false;	
	sum7=a[0]+a[4]+a[8];
	sum8=a[2]+a[4]+a[6];
	se.insert(sum7);
	se.insert(sum8);
	if(se.size()!=8)
		return false;
	return true;	
}
int main(void)
{
	int sum=0;
	do
	{	
		if(check())
		{
			sum++;
		}
	}while(next_permutation(a,a+9));
	printf("%d\n",sum/8);
	return 0;
}
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
int a[10]={1,2,3,4,5,6,7,8,9};
int ans;
int main(void)
{
	do
	{
		set<int>st;
		int sum=0;
		for(int i=0;i<3;i++) sum+=a[i];
		st.insert(sum),sum=0;
		for(int i=3;i<6;i++) sum+=a[i];
		st.insert(sum),	sum=0;
		for(int i=6;i<9;i++) sum+=a[i];
		st.insert(sum),	sum=0;
		for(int i=0;i<3;i++) sum+=a[i*3];
		st.insert(sum),	sum=0;
		for(int i=0;i<3;i++) sum+=a[i*3+1];
		st.insert(sum),	sum=0;
		for(int i=0;i<3;i++) sum+=a[i*3+2];
		st.insert(sum),	sum=0;
		sum=a[0]+a[4]+a[8];
		st.insert(sum),	sum=0;
		sum=a[2]+a[4]+a[6];
		st.insert(sum),	sum=0;
		if(st.size()==8) ans++;
	}while(next_permutation(a,a+9));
	cout<<ans/8<<endl;
//	cout<<24960/8<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值