凑平方数

题目描述
题目出处https://www.lanqiao.cn/problems/653/learning/
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
把 0 ~ 9 这 10 个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。

比如:
0, 36, 5948721
copy
再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376

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

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

运行限制
最大运行时间:1s
最大运行内存: 128M
思路:
利用二进制数的特点,记录每一个平方数的各个位的数的使用情况,再枚举算出满足题意的平方数并存储其状态。然后dfs排列所有满足条件的可能就可以了。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 1 << 10;
int ans;
vector<int> nums;//存放符合条件平方数,数字的状态 
void check(LL x) {
  int status = 0;//记录数字的状态,初始时全部标记为0
  if (x == 0) status = 1;//标记最低位即第0位为1
  while (x) {
    //获取10进制个位上的数,1移位后与上一次的状态做与运算
    //不为0说明个位上的数字已经被使用,则不记录,return
    if ((status & (1 << (x % 10))) != 0) return;
    
    //记录数字使用情况
    status |= (1 << (x % 10)); //标记个位对应位置为1
    x /= 10; //消掉个位 
  }
  nums.push_back(status);
}
void dfs(int x, int y) {//从第x个合法数字往后取,当前组合状态为y
  if (y == maxn - 1) {//组合可行,记录答案 
    ans++;
    return;
  }
  for (int i = x; i < nums.size(); i++) {//枚举新加入数字的状态
    if ((nums[i] & y) == 0) { //可以加入组合,去找下一个数字
      dfs(i + 1,nums[i] | y); 
    }  
  }
}
int main() {
  //枚举算出满足题意的平方数并存储其状态
  for (LL i = 0; i <= 100000; i++) {
    check(i * i);
  }
  //用深搜按顺序组合预处理出的平方数
  dfs(0,0);
  cout << ans << endl;
  return 0; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值