第七届蓝桥杯决赛真题 - 凑平方数

题目:

凑平方数
把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够
办到的。

比如:0, 36, 5948721

再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等…

注意,0可以作为独立的数字,但不能作为多位数字的开始。
分组时,必须用完所有的数字,不能重复,不能遗漏。

如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?

注意:需要提交的是一个整数,不要填写多余内容。

解题思路:
先用全排列列举出所有可能的序列,然后对每一个序列使用dfs搜索平方数组,接着最后使用set容器的特点进行查重。

注意问题:
1.排序的时候不要直接对原数组进行排序,否则回溯后会影响之前的数
2.用string保存每一组情况,两个数之间需要用一个标记(‘-’)进行分隔
3.数的范围可能会超过int,所以使用long long类型

知识点:
平方数判断、全排列、dfs搜索、查重(利用set容器)

答案:
300

C++代码:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <set>
#include <string>
using namespace std;

int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
long long nums[10];
set<string> res;

//判断一个是否为平方数 
bool isqnum(long long num){
    double d = sqrt(num);
    return d == (long long)d;
}

//从arr:[i, n)寻找平方数 
void dfs(int i, int n){
    if(i == 10){
        long long nums_t[10];
        copy(nums, nums + n, nums_t);
        sort(nums_t, nums_t + n);
        string s;
        for(int j = 0; j < n; ++ j){
            s += to_string(nums_t[j]) + ',';
        }
        res.insert(s);
        return ;
    }

    if(arr[i] == 0){
        nums[n] = 0;
        dfs(i + 1, n + 1);
        return;
    }

    long long num = 0;
    for(int j = i; j < 10; ++ j){
        num = num*10 + arr[j];
        if(isqnum(num)){
            nums[n] = num;
            dfs(j + 1, n + 1);
        }
    }
}


int main(){
    do{
        dfs(0, 0);
    }while(next_permutation(arr, arr + 10));
    cout << res.size()  << endl;
    return 0;
}
展开阅读全文
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值