博客版权已保护:转载请注明出处,谢谢。

第七届蓝桥杯国赛 凑平方数(dfs+set去重)

【题目】

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

比如:0, 36, 5948721

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

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

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

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

【分析】

首先利用全全排列函数列举出所有的组合,然后利用dfs搜索每一个满足的组合,在查找的过程中利用排序+set容器来去重复(这是一种较为常见的去重方法,注意要排序),dfs过程中,要判断一个数是否为平方数,还要对特殊的情况进行特判。
【知识点】

全排列,dfs,平方数判断,set去重

【代码】

#include <bits/stdc++.h>
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;
        long long int ju = 0;
        for(int j = 0; j < n; ++ j){
            string te = "";
            stringstream stream;
            stream << nums_t[j];
            stream >> te;
            s += te + ",";
        }
        cout << s << endl;
        res.insert(s);
        return ;
    }

    if(arr[i] == 0){  //特判a[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;
}

//(代码参考:https://blog.csdn.net/luoluozlb/article/details/72581286,但是原来的to_string函数用不了,所以用上了stream函数);

【补充】
stream函数是c++中重要的一个函数,有关输入流,输出流,字符串流等,再转换整型与字符串之间起着重要的作用。这里是学习链接:stream (什么时候,我回头记起来了,再来写一篇关于stream的)。


 

【记录心情】
5月25号就是蓝桥杯国赛了,虽然蓝桥杯的含金量跟ACM赛事是没法比的,但是还是希望自己能拿到国2以上的成绩,因为好像已经没有机会再去打ACM类的比赛了。。。

posted on 2019-04-07 15:52  superhero11  阅读(465)  评论(0编辑  收藏  举报

导航