Codewars进阶之路——Getting along with Integer Partitions(DFS)

这道题原意是输入一个整数,然后将其分解为若干个数字的和,例如:

5 = 5
5 = 4 + 1
  ·
  ·
  ·
5 = 1 + 1 + 1 + 1 + 1

于是这样就形成了一个集合:

enum(5)-> [[5],[4,1],[3,2],[3,1,1],[2,2,1],[2,1,1,1],[1,1,1,1,1]]

接下来计算每个子集合的积(product),并去重、排序,于是得到:

prod(5) -> [1,2,3,4,5,6]

接下来就是求这个数组中的极差、平均数和中位数了
我的方法比较“暴力”,就是先把所有的集合都先求出来,合并到一个set里面,也就是先得到prod集合,接下来按部就班即可。
过程中遇到的难点主要有两个:DFS和保留两位小数
先说后一个,平时保留的时候都是在输出的时候,即

cout<<setprecision(2)<<number;

但还没遇到说将结果保留小数放进string里面的,后来是用到了以前C里面的一个函数sprintf解决,不知道有没有其它办法(后来看了别人的solution还可以用ostringstream方法)
至于DFS,这个其实很好理解,比什么走迷宫简单多了,最开始的时候是得到1+1+1+···+1这个式子,然后1+1+···+2,直到只有n为止
贴出完整pass的代码:

#include <set>

int n, total;
int res[100000];
int times;
std::set<long long> s;
long long sum;

class IntPart
{
public:
static void dfs(int index, int n)
{
    if (total == n)
    {
        long long num = 1;
        for (int i = 0; i < times; ++i)
            num *= res[i];
        s.insert(num);
        return;
    }
    if (total > n) return;
    for (int i = index; i <= n; ++i)
    {
        total += i;
        res[times++] = i;
        dfs(i, n);
        total -= i;
        res[times--] = 0;
    }
}

  static std::string part(long long n)
  {
    sum = 0;
    s.clear();
    memset(res, 0, sizeof(int));
    times = 0;
    total = 0;
    dfs(1, n);

    int size1 = s.size(), pos = 0, size2;
    long long med1, med2;
    if (size1 % 2) size1 = size2 = size1 / 2;
    else
    {
        size1 = size1 / 2, size2 = size1 - 1;
    }
    int low, high;
    std::set<long long>::iterator it = s.begin();
    for (; it != s.end(); ++it, ++pos)
    {
    sum+=(*it);
        if (pos == 0) low = (*it);
        if (pos + 1 == s.size()) high = (*it);
        if (pos == size1) med1 = (*it);
        if (pos == size2) med2 = (*it);
    }
    std::string ans = "Range: " + std::to_string(high - low) + " Average: ";
  std::string sAve, sMed;
  char cc[10] = {0};
    float Ave = sum*1.0 / pos;
  std::sprintf(cc, "%.2f", Ave);
  sAve = cc;


    float Med = (med1 + med2)*1.0 / 2;
  std::sprintf(cc, "%.2f", Med);
  sMed = cc;


    ans = ans + sAve + " Median: " + sMed;
    return ans;
  }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值