2016年第七届蓝桥杯【C++决赛赛B组】【第二题:凑平方数】——全排列+暴力DFS

标题:凑平方数


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


再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等...


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


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


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


#include<bits/stdc++.h>
using namespace std;
int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
long long num[10];
set<string> s;
void dfs(int step, int k) {//已经使用了step个数,凑成了k个新数
  if(step == 10) {
    string str;
    long long temp[10];//另开一个数组复制已经搜完的数组再进行操作,不能直接操作搜索数组,会影响回溯 
    for(int i = 0; i < k; i++)
      temp[i] = num[i];//复制数组,两个数组要是同一类型 
    sort(temp, temp+k);
    for(int i = 0; i < k; i++) {
      char buff[100];//因为是存lld格式的,所以数组要开大来 
      sprintf(buff, "%lld", temp[i]);
      str += buff;
      str += "-";
    }
    s.insert(str);
    return;
  }
  if(a[step] == 0) {//这一步走到当前数为0,直接取,0不能作为开头数,并且0也是一个平方数
    num[k] = 0;
    dfs(step+1, k+1); 
  }else{//保证这一数不以0开头
    long long sum = 0;
    for(int i = step; i < 10; i++) {//遍历取多少个数
      sum = sum * 10 + a[i];
      double p = sqrt(sum);
      if(p - (int)p == 0) {//当前构成的数为平方数 
        num[k] = sum;
        dfs(i+1, k+1);
      } 
    } 
  }
}
int main() {
  do {
    memset(num, 0, sizeof(num));
    dfs(0, 0);
  }while(next_permutation(a, a+10));
  printf("%d\n", s.size());
  return 0;
}

猜你喜欢

转载自blog.csdn.net/daixinliangwyx/article/details/79964648