把 0 ~ 9这 10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。
比如:
0, 36, 5948721
再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
...
注意,0 可以作为独立的数字,但不能作为多位数字的开始。 分组时,必须用完所有的数字,不能重复,不能遗漏。
如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
思想:
如果考虑先分组,然后再枚举分组内每个数,有点困难。不如先遍历出所有的平方数,将合格的平方数存入数组中。(合格的平方数就是每一位没有重复的平方数)然后DFS遍历所有的数组,看能不能凑成刚好0到9共10个整数都含有了。如果有,结果+1。
为了方便比较0到9这10个数,可以采用状态的方法,将这个数的状态存入数组。然后直接操作状态即可。
这里也用到了位运算,如&运算判断某个元素是否在集合中,|运算将某元素并入集合中,需要自己体会。
代码:
#include <iostream>
#include <vector>
#include <cstring>
typedef long long LL;
using namespace std;
vector<LL> vec;
LL ans = 0;
bool check(LL x) {
int state = 0;
if (x == 0) state = 1;
while (x) {
if (state & (1 << (x % 10))) {
return false;
}
state |= (1<< (x % 10));
x /= 10;
}
vec.push_back(state);
return true;
}
void dfs(int x, int y) {
if (y == ((1<<10) - 1)) {
ans++;
return;
}
for (int i = x; i < vec.size(); i++) {
if ((y & vec[i]) == 0) {
dfs(i + 1, y | vec[i]);
}
}
}
int main() {
for (LL i = 0; i <= 100000; i++) {
check(i * i);
}
dfs(0, 0);
cout << ans << endl;
return 0;
}
答案我就不写了,为了不影响做题,你们自己运行一下。
可以在蓝桥云课测试运行。