zoukankan      html  css  js  c++  java
  • HDU 1258 Sum It Up(Dfs)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1258

    题意:sum  n    n个数,输出所有和为sum的组合,要非递增且不能重复如第三个样例:本来可以有多个50+50+50+50+50+50+25+25+25+25,但是只输出了一个

    这里有两点:1~怎么输出非递增的组合。。。。由于他输入就按非递增的了。。。所以我Dfs的for()从最后一个被用的下一位开始找。。。。保证下一个数是在目前最后一个被用的数字的后面。。。

    2~怎么判重,本来可以求SUM然后从低位像a+b*sum+c*sum*sum的形式Hash,但是1000^12太大了。。。,由于最多只有12个数,且每个数字最多两位,所以我想到把数字Hash成字符串然后用set来判重。。。。

    代码:

    #include <iostream>
    #include <string>
    #include <set>
    using namespace std;
    
    const int  M = 100 + 10;
    
    set <string> s;
    int save[M];
    int ans[M];
    bool used[M];
    int sum;
    int n;
    int flag;
    
    
    void Dfs(int now, int now_sum)
    {
    
    
        if (now_sum == sum)
        {
            string str;
            for (int i = 1; i <= now; i++)//把这些数字Hash成字符串,用来判重
            {
                str += (ans[i] / 10) + '0';
                str += ans[i] % 10 + '0';
            }
    
            if (s.find(str) == s.end())
            {
                s.insert(str);
                flag = 1;
                for (int i = 1; i <= now; i++)
                {
                    printf(i == 1 ? "%d" : "+%d", ans[i]);
                }
                puts("");
            }
            return ;
        }
        int j;
        for (j = n; j >= 1 && !used[j]; j--);//找最后一个被用的位置
    
        for (int i = j + 1; i <= n; i++)//从最后一个被用的下一位开始,保证非递增
        {
            if (!used[i] && now_sum + save[i] <= sum)
            {
                used[i] = 1;
                ans[now+1] = save[i];
                Dfs(now + 1, now_sum + save[i]);
                used[i] = 0;
            }
        }
    }
    
    int main()
    {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w",stdout);
        while (~scanf("%d%d", &sum, &n), n)
        {
            printf("Sums of %d:\n", sum);
            for (int i = 1; i <= n; i++)
            {
                scanf("%d", save + i);
            }
    
            flag = 0;
            memset(used, 0, sizeof(used));
            s.clear();
            Dfs(0, 0);
            if (flag == 0)
            {
                puts("NONE");
            }
        }
        return 0;
    }
  • 相关阅读:
    linux docker常用命令
    angular input输入框自动消除前后空格
    angular 一览数据全选符合条件数据
    linux MySQL出现错误的一些常见解决办法
    linux crontab定时任务一些命令
    Linux下定时访问指定url地址
    直接打印对象的结果
    java中变量的作用域
    请求转发后地址栏显示传入的值,页面不显示的原因
    String不是基本数据类型,但是
  • 原文地址:https://www.cnblogs.com/qiufeihai/p/2679310.html
Copyright © 2011-2022 走看看