凑算式
B DEF
A +---- + ------- = 10
C GHI
(如果显示有问题,可以参见【图1.jpg】)
这个算式中AI代表19的数字,不同的字母代表不同的数字。
比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。
这个算式一共有多少种解法?
29
注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。
解题思路1:利用next_permutation(a,a+n)函数
注意分数相加减 数组要定义为double类型的, 下面的和也要是double类型的 包括10;
关于next_permutation()函数的使用 下面给出讲解
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int a[4]={1,2,3,4};
do{
cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl;
}while(next_permutation(a,a+4));
system("pause");
return 0;
}
即求括号中内容的下一个排列。如:a[4]={1,2,3,4}.next_permutation(a,a+4) 即为1,2,4,3.
函数原型:
若为4,3,2,1.next_permutation的返回值即为false,因为没有下一个排列。但是经过一次函数调用之后会变为1,2,3,4.
与之相对的还有一个函数为prev_permutation() 顾名思义,该函数为求上一个排列。
百度百科中的解释如下:
next_permutation函数将按字母表顺序生成给定序列的下一个较大的排列,直到整个序列为降序为止。prev_permutation函数与之相反,是生成给定序列的上一个较小的排列。二者原理相同,仅遍例顺序相反
问题:如何求一个数组的下一个排列?
假设该数组为3 6 4 2.下一个排列应为 4 2 3 6.
过程:对于一个任意序列,最小的排列是增序,最大的为减序。
从最后一位向前看,首先得到的是2,单纯的一个数不需要进行交换。
然后得到的是 4 2,4大于2,在这个子序列中已经为最大序列,无法排出更大的序列了。
然后得到的是 6 4 2,原理同上。
之后得到的是 3 6 4 2,此时由于3小于6且小于4,而 3 6 4 2的下一个排列应为比3 6 4 2这个排列大的排列中最小的那个,所以3应该和4进行交换,此时该排列变为 4 6 3 2.此时4位于首端,所以之后的序列应为最小序列,即 2 3 6.综上,最终结果应为 4 2 3 6.
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
double a[10] = {1,2,3,4,5,6,7,8,9};
int ans = 0;
int main(){
while(next_permutation(a,a + 9)){
double sum = a[0] + (a[1] / a[2]) + (a[3] *100 + a[4] * 10 + a[5]) / (a[6] * 100 + a[7] * 10 + a[8]);
if(sum == 10.0){
ans++;
}
}
cout << ans;
return 0;
}
解题思路2:dfs递归搜索
注意分数相加减 数组要定义为double类型的, 下面的和也要是double类型的 包括10;
或者在分子后面 * 1.0 表示转换为double类型的数字
#include <iostream>
using namespace std;
double a[9] = {0};
int ans = 0;
bool judge(double a[]){
double sum = a[0] + (a[1] * 1.0 / a[2]) + (a[3] *100 + a[4] * 10 + a[5]) * 1.0/ (a[6] * 100 + a[7] * 10 + a[8]);
if(sum == 10.0){
return true;
}
return false;
}
bool check(int num){
for(int i = num - 1;i >= 0;i--){
if(a[i] == a[num]){//注意判断重复的条件
return false;
}
}
return true;
}
void dfs(int x){
if(x > 8){
if(judge(a)){
ans++;
}
return;
}
for(int i = 1;i < 10;i++){
a[x] = i;
if(check(x)){//注意检查的是参数的值 不是循环i的值
dfs(x + 1);
}
}
}
int main(){
dfs(0);
cout << ans;
return 0;
}
解题思路3:暴力
因为是分数当中涉及到除法 尽量不要用除法,因为里面涉及到精度的问题,我试了一次 出错了 答案不对 (当时没有考虑到int 和double 类型的问题)
可以使用下面的方法 通分过后比较
也可以使用下面的方式 进行转换为double类型的
if(a + ((b * 1.0) / c) + (d * 100 + e * 10 + f) * 1.0 /(g * 100 + h * 10 + j) == 10){
ans += 1;
}
#include<iostream>
#include <algorithm>
using namespace std;
int main(){
int ans = 0;
int a,b,c,d,e,f,g,h,j;
for(int a = 1;a <= 9;a++){
for(int b = 1;b <= 9;b++){
if(a == b){
continue;
}
for(int c = 1;c <= 9;c++){
if(a == c || b == c){
continue;
}
for(int d = 1;d <= 9;d++){
if(a == d || b == d || c == d){
continue;
}
for(int e = 1;e <= 9;e++){
if(a == e || b == e || c == e || d == e){
continue;
}
for(int f = 1;f <= 9;f++){
if(a == f || b == f || c == f || d == f || e == f){
continue;
}
for(int g = 1;g <= 9;g++){
if(a == g || b == g || c == g || d == g || e == g || f == g){
continue;
}
for(int h = 1;h <= 9;h++){
if(a == h || b == h || c == h || d == h || e == h || f == h || g == h){
continue;
}
for(int j = 1;j <= 9;j++){
if(a == j || b == j || c == j || d == j || e == j || f == j || g == j || h == j ){
continue;
}
/*if(a + ((b * 1.0) / c) + (d * 100 + e * 10 + f) * 1.0 /(g * 100 + h * 10 + j) == 10){
ans += 1;
} */
int t1 = a * c * ( 100 * g + 10 * h + j );
int t2 = b * (100 * g + 10 * h + j);
int t3 = c * (100 * d + 10 * e + f);
int t4 = 10 * c * (100 * g + 10 * h + j);
if( t1 + t2 + t3 == t4)ans++;
}
}
}
}
}
}
}
}
}
cout << ans;
return 0;
}