题目:
凑平方数
把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够
办到的。比如:0, 36, 5948721再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等…注意,0可以作为独立的数字,但不能作为多位数字的开始。
分组时,必须用完所有的数字,不能重复,不能遗漏。如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?注意:需要提交的是一个整数,不要填写多余内容。
解题思路:
先用全排列列举出所有可能的序列,然后对每一个序列使用dfs搜索平方数组,接着最后使用set容器的特点进行查重。
注意问题:
1.排序的时候不要直接对原数组进行排序,否则回溯后会影响之前的数
2.用string保存每一组情况,两个数之间需要用一个标记(‘-’)进行分隔
3.数的范围可能会超过int,所以使用long long类型
思路链接:https://blog.csdn.net/luoluozlb/article/details/72581286
代码如下:
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <set>
using namespace std;
int a[] = {0,1,2,3,4,5,6,7,8,9};
typedef long long LL;
const int N = 20;
LL used[N];
LL tmp[N];//数字很大,要用longlong来存set<string>ans;
int k;
void dfs(int u)
{if (u==10){string str = "";copy(used,used+k,tmp);
// for (int i = 0;i<k;i++)
// {
// cout<<tmp[i]<<" ";
// }
// cout<<endl;sort(tmp,tmp+k);//要排序,不然会因为顺序不同,导致很多一样的情况都重复算了for (int i = 0;i<k;i++){char s[20];sprintf(s,"%lld",tmp[i]);str+=s;str+='-';//每组之间拿-隔开}
// cout<<str<<endl;ans.insert(str);return ;}if (a[u]==0)//0不能为数字开头,所以我们这样处理{used[k++] = 0;dfs(u+1);used[--k] = 0;}else {LL t = 0;for (int i = u;i<10;i++ ){t = t*10+a[i];LL x = sqrt(t);if (x*x==t){used[k++] = t;dfs(i+1);used[--k] = 0;}}}
}int main()
{do{k = 0;dfs(0);}while(next_permutation(a,a+10));cout<<ans.size()<<endl;return 0;
}