C语言课程设计——随意组合

设计题目——随意组合

1.题目背景(来自某年蓝桥杯竞赛题)

小明被绑架到X星球的巫师W那里。当时,W正在玩弄两组数据 (2 3 5 8) 和(1 4 6 7),他命令小明从一组数据中分别取数与另一组中的数配对,共配成4对(组中的每个数必被用到)。
小明的配法是:{(8,7),(5,6),(3,4),(2,1)}
巫师凝视片刻,突然说这个配法太棒了!
因为:每个配对中的数字组成两位数,求平方和,无论正倒,居然相等:
87^2 + 56^2 + 34^2 + 21^2 = 12302
78^2 + 65^2 + 43^2 + 12^2 = 12302
小明想了想说:“这有什么奇怪呢,我们地球人都知道,随便配配也可以啊!”
{(8,6),(5,4),(3,1),(2,7)}
86^2 + 54^2 + 31^2 + 27^2 = 12002
68^2 + 45^2 + 13^2 + 72^2 = 12002
巫师顿时凌乱了。。。。。
请你计算一下,包括上边给出的两种配法,巫师的两组数据一共有多少种配
对方案具有该特征。
配对方案计数时,不考虑配对的出现次序。
就是说:{(8,7),(5,6),(3,4),(2,1)}与{(5,6),(8,7),(3,4),(2,1)}是同一种
方案。

2. 题目要求

题目中提出 : 87^2 + 56^2 + 34^2 + 21^2 = 12302
78^2 + 65^2 + 43^2 + 12^2 = 12302
即证明 两组数,分别对应组合成两位数,然后各自平方的和等于这个两位数交换次序后,平方的和。
即: (x1 y1 )_^2+ (x2 y2 )^2+(x3 y3 )^2+(x4 y4 )^2=(y1 x1 )^2+(y2 x2 )^2+(y3 x3 )^2+(y4 x4 )^2
当满足这个公式的组合,就是满足题意的组合。

3. 解决办法

从上一个小节中,要验证组合数,满足这个公式,首先需要一个取反的函数。

先将公式前者计算出来,保存在sum1中。使用取反函数后,再次计算。最后比较二者的值。若相等 ans 加 1 。

第二个问题就是,怎么变换组合数的顺序。并且要有所有的组合结果。通过查找库函数,我得到了一个名为 next_permutation 的函数 ,用于求下一个排列。next_permutation(start,end) start 是起始位置 end 是终止位置

在这里 我需要将 保存组合数数组的起始位置和终止位置,写入就可以
即:next_permutation(arr1,arr1+4);
当所有排列求完时,返回值 -1 所以我想到了,加一个while(tmp)作为程序结束的条件

4. 流程图在这里插入图片描述

5.代码实现

//#include<bits/stdc++.h>  //万能包 
//#include <iostream>
#include<stdio.h> 
#include<algorithm> //库函数  next_permutation 的头文件。 
using namespace std;

	int f(int x)//X数取反 
	{
 		int m = 0;
 		m += x / 10;
 		m += (x%10)*10;
 		return m;
	}
	int main()
	{
 		int arr1[4] = {2, 3, 5, 8};
 		int arr2[4] = {1, 4, 6, 7};
 		int tmp = 1, a, b, c, d, sum1, sum2, ans;
 		ans = 0;
 		while(tmp)
 		{
 			a = arr1[0]*10 + arr2[0];
 			b = arr1[1]*10 + arr2[1];
 			c = arr1[2]*10 + arr2[2];
 			d = arr1[3]*10 + arr2[3];
 			sum1 = a*a + b*b +c*c + d*d;
 			sum2 = f(a)*f(a) + f(b)*f(b) + f(c)*f(c) + f(d)*f(d);
 			if(sum1 == sum2)
  				ans++;
 			tmp = next_permutation(arr1, arr1+4);//库函数  求下一个排列 
 		}
 	printf("%d\n", ans);
 	return 0;
}
 

6. 运行结果

在这里插入图片描述

7 . 心得体会

在设计这个程序的时候,求数组排列是个难点。可以穷举法都列出来。但我通过查资料找到了C++库函数,简化了程序,使程序高效运行。在这个过程中我学到了,遇到一个数学问题,可以通过查找库函数来解决。提高自己的查阅资料的能力,以及运用新知识的能力。

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值