凑平方数 - 蓝桥杯2016

凑平方数

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

再比如:

1098524736
1, 25, 6390784
0, 4, 289, 15376

等等...

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

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

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

答案: 300 

 

注意了 官方答案是300!不是某个差一点(由于 int 没改成 ll )拿国一的博主说的 !正确答案 263 !!!

网上有的博主用的JAVA大整数做的 那么我就用C++ 暴力来写吧

 

思路:

通过next_permutation() 进行”0123456789“ 的全排列

然后对每一个排列都扫描一下,看能不能分成几个平方数

扫描通过 dfs来实现

每层dfs处理自己得到的串时

从 pos 位置(每层dfs 的串开始位置)开始 取一个 或者俩个,三个,四个......取全部,然后把剩下的交给下一个dfs 

然后判断这几个数字组成的数能否开方,是继续,否则跳过。

嘛~~~ 说起来简单........

 

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <set>
using namespace std;
int num = 0;
// 通过 东东学长教的 set神器 来查重 (有点硬核。。。)
set< set<int> > vs;
void dfs(string s,int pos,set<int> ss){
    if(pos == 10){
        vs.insert(ss);
        num++;
    }
    int len = s.size();
    long long sum = 0;
    for(int i=pos;i<len;++i){
        //把从 s[pos-i] 变为整数  
        sum*=10;
        sum+=(s[i]-'0');
        // 看是不是可以开方
        double x = sqrt(sum);
        // 如果第一个是0且长度为 1 或者 第一个不为0 是个能被开方的数
        if( (s[pos] =='0'&& i == pos) || (s[pos]!='0' && x == double((long long)(x)))  ) {
            ss.insert(sum);
            dfs(s,i+1,ss); 
            ss.erase(sum);
        }
    }
}
int main(){
    // 来一次全排列!
    string s="0123456789"; 
    set<int> ss;
    do{
        //每次都把这次排列扫一遍
        dfs(s,0,ss);
    }while(next_permutation(s.begin(),s.end()));
    cout<<vs.size()<<endl;
    cout<<num<<endl;
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值