题目:
凑平方数
把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;
}