每日一题:凑算式(全排列)

之前做过这道题,当时想的是爆搜的做法,今天发现其实可以用全排列做

题目

凑算式

     B      DEF
A + --- + ------- = 10
     C      GHI

(如果显示有问题,可以参见【图1.jpg】)


这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。

比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。

这个算式一共有多少种解法?

注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。

全排列的解法

每一次找到一个可能的结果就直接判断是否和等于10就行
我们通过内置的全排列函数next_permutation去生成不同的可行解,每一次去验证是否正确


#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int a[]={1,2,3,4,5,6,7,8,9};

int ans=0;
bool check(){
    int x = a[3] * 100 + a[4] * 10 + a[5];
    int y = a[6] * 100 + a[7] * 10 + a[8];
    if(a[0] + a[1]/a[2] + x/y == 10)
        return true;
    return false;
}
//递归回溯生成全排列,适用于无重复元素的情况
int main(int argc, const char * argv[]) {
    do{
        if(check())
            ans++;
    }while(next_permutation(a,a+9));
    cout<<ans<<endl;
    return 0;
}

结果竟然是:29807
不对哇,为什么呢?
发现有的时候B/C+DEF/GHI不是整数,需要先通分再求和。

a[0] + (a[1] * y + a[2] * x) / (y * a[2]) == 10

得出结果竟然是:35721
发现还是不行??为什么结果越来越大了???
这样计算,整数和整数加和会自动舍弃小数,所以需要确保后面两项的和一定是整数:

if((a[1] * y + a[2] * x) % (y * a[2])==0 && a[0] + (a[1] * y + a[2] * x) / (y * a[2]) == 10

这样才是正确的结果

手动全排列

就是从第一个位置开始找,跟全排列的思想一样

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int a[]={1,2,3,4,5,6,7,8,9};
int ans;
bool check(){
    int x = a[3] * 100 + a[4] * 10 + a[5];
    int y = a[6] * 100 + a[7] * 10 + a[8];
    if((a[1] * y + a[2] * x) % (y * a[2])==0 && a[0] + (a[1] * y + a[2] * x) / (y * a[2]) == 10)
        return true;
    return false;
}
//递归回溯生成全排列,适用于无重复元素的情况
void f(int k) {
    if(k==9){//一种排列已经生产
        if(check())
            ans++;
    }
//    从k往后的每个数字都可以放在k位
    for (int i = k; i < 9; ++i) {
        {int t=a[i];a[i]=a[k];a[k]=t;}
        f(k+1);//递归
        {int t=a[i];a[i]=a[k];a[k]=t;}//回溯
    }
}
int main(int argc, const char * argv[]) {
    f(0);
    cout<<ans<<endl;
    return 0;
}

第七届蓝桥杯省赛第三题,难度因该还好,很经典的一道题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shirandexiaowo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值