蓝桥杯 立方和等式 数的全排列



考虑方程式:a^3 + b^3 = c^3 + d^3
其中:“^”表示乘方。a、b、c、d是互不相同的小于30的正整数。
这个方程有很多解。比如:
a = 1,b=12,c=9,d=10 就是一个解。因为:1的立方加12的立方等于1729,而9的立方加10的立方也等于1729。
当然,a=12,b=1,c=9,d=10 显然也是解。
如果不计abcd交换次序的情况,这算同一个解。
你的任务是:找到所有小于30的不同的正整数解。把a b c d按从小到大排列,用逗号分隔,每个解占用1行。比如,刚才的解输出为:
1,9,10,12


不同解间的顺序可以不考虑。


对于这种题目,首先我们要做的是预处理,因为一共只有30个数字,所以可以事先将1-30中的每个数字求出其立方然后保存起来,便于后面运算。然后,我们对这30个数字取四个进行全排列,总共就是P(30,4)种可能,其实还是很少的,所以枚举应该不会出现大问题,所以问题的关键是怎样求全排列,首先,我们定义两个数组,cubic[]和used[],分别代表那三十个数的立方和每个数字是否被使用,然后,我们通过一个递归程序,递归总共四层,用count来控制,每一层代表一个加数,temp[]用来临时存储这四个数,每使用一个数,就将这个数标记一下,别忘了在回溯的时候解除标记,这样就可以无重复全排列了,取出四个数之后,判断一下等式是否成立,如果成立并且之前没有出现过的话,就将这组解存到result[][]中,最后输出result[][]。

#include<iostream>
#include<stdio.h>
#include<memory.h>
#include<algorithm>
using namespace std;
int cubic[31];
bool used[31];
int result[100][4];
int temp[5];
int p,q;
void init()
{
	int i;
	p=0;
	q=0;
	for(i=1;i<=30;i++)
	{
		cubic[i]=i*i*i;
	}
	memset(used,false,sizeof(used));
}

bool search()
{
	int i;
	sort(temp,temp+5);
	for(i=0;i<p;i++)
	{
		if((result[i][0]*result[i][0]*result[i][0])==temp[1]&&(result[i][1]*result[i][1]*result[i][1])==temp[2])
		return true;
	}
	return false;
}

void judge()
{
	if(temp[1]+temp[2]==temp[3]+temp[4])
	{
		if(search())
		return;
		for(int i=1;i<=30;i++)
		{
			for(int j=1;j<=4;j++)
			{
				if(temp[j]==cubic[i])
				{
					result[p][q++]=i;
				}
			}
		}
		p++;
		q=0;
	}
}
void cal(int count)
{
	if(count==5)
	{
		judge();
		return;
	}
	int i;
	for(i=1;i<=30;i++)
	{
		if(used[i]==false)
		{
			temp[count]=cubic[i];
			used[i]=true;
		    cal(count+1);
		    used[i]=false;
		}
	}
}
int main()
{
	int i,j;
	init();
	cal(1);
	for(i=0;i<p;i++)
	{
		for(j=0;j<4;j++)
		cout<<result[i][j]<<' ';
		cout<<endl;
	}
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值