| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1868 人关注过本帖, 1 人收藏
标题:算数问题,求算法
只看楼主 加入收藏
红色沂蒙
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2013-4-3
收藏(1)
 问题点数:0 回复次数:12 
算数问题,求算法
99    3    351    165    54    297    9    1053    495    162    126    75    378    225   
198    6    702    330    108    594    18    2106    990    324    252    150    756    450   
297    9    1053    495    162    891    27    3159    1485    486    378    225    1134    675   
396    12    1404    660    216    1188    36    4212    1980    648    504    300    1512    900   
495    15    1755    825    270    1485    45    5265    2475    810    630    375    1890    1125   
594    18    2106    990    324    1782    54    6318    2970    972    756    450    2268    1350   
693    21    2457    1155    378    2079    63    7371    3465    1134    882    525    2646    1575   
792    24    2808    1320    432    2376    72    8424    3960    1296    1008    600    3024    1800   
891    27    3159    1485    486    2673    81    9477    4455    1458    1134    675    3402    2025   

如何用以上数字之中的某些数字相加等于 2894 。算一宿了没算出来!!!
搜索更多相关主题的帖子: 225 150 
2013-04-03 23:30
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
好像数据太大,跑了很久都没结果,倒是求300就正确
程序代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define SUM 300

int a[9*14];
int ss[100];

void output(int n)
{
    int i;
    FILE *fp;
    fp = fopen("out.txt", "a");
    for (i = 0;i < n-1;++i)
    {
        fprintf(fp, "%d + ", ss[i]);
    }
    fprintf(fp, "%d = %d\n\n", ss[i], SUM);
    fclose(fp);
}

void cal(int sum, int i, int flag)
{
    if (sum == SUM)
    {output(flag);return;}

    while (i < 9*14 && sum + a[i] <= SUM)
    {
        sum += (ss[flag] = a[i]);
        cal(sum, ++i, flag+1);
        sum -= ss[flag];
    }
}

void getnumber()
{
    int i;
    FILE *fp;
    
    fp = fopen("aa.txt", "r");
    for (i = 0;i < 9*14;++i)
    {
        fscanf(fp, "%d ", &a[i]);
    }
    fclose(fp);
}

int cmp(const void *a, const void *b)
{
    return *(int *)a - *(int *)b;
}

int main()
{
    FILE *fp;
    getnumber();
    fp = fopen("out.txt", "w");
    qsort(a, 9*14, 4, cmp);
    fclose(fp);cal(0, 0, 0);
    return 0;
}


[fly]存在即是合理[/fly]
2013-04-04 16:45
fanpengpeng
Rank: 8Rank: 8
来 自:南极洲
等 级:蝙蝠侠
威 望:7
帖 子:299
专家分:849
注 册:2013-2-1
收藏
得分:0 
觉得这个题目还有点意思 就花了点时间做了下
这个题目的规模实在是大 别看就只有126个数据 但是问题搜索范围是2的126次方
没估算过 所有情况都一一遍历的话 需要多长时间 应该是需要很久的
这类运算量大的题目 保留中间计算结果 尽量减少重复计算的次数 应该是一个好的优化算法的思路
我在2楼的递归算法的基础上 做了3点改进
仍然是从大到小排序 从大数开始选择 但是每次递归改为求解剩余需要组合的值 比如sum=9 已经选择了 6 那么从6之后 求解能合成3的方法
具体改进的地方:
1. 向后搜索时 不是一一搜索 而是跳过比sum值大的值 因为他肯定不是有效组合 只要加上他就超了 就不用试了
2. 判断如果这之后所有的值都加起来的和比sum值要小 那么就终止本轮搜索 向前回溯 因为即使加上所有值 都组不成有效解
3. 保留中间过程的计算结果 比如在求解过程中 发现 在搜索sum=9时 从位置5往后没有可行解
   那么下次再要搜索9时而且起始位置在5或之后 就根据这个信息直接结束递归并向前回溯
其实 起到真正效果的是 第3点 前两点的优化效果不是很明显

但是 不幸的是 经过求解发现 楼主给的2894是找不到有效组合的 有可能是真的没有可行解 不过结论仅供参考

下面是代码 发现bug 欢迎指出 不懂算法 纯属个人瞎编
编译器 mingw5,C编译器不支持内置bool 请修改代码中相应符号定义
程序代码:
#include <stdio.h>
#include <stdlib.h>

#define Compiler_CPP    //编译器类型 判断是否支持内置bool类型
#define Display_ON        //控制台显示开关 是否打开中间过程显示

#define IN_FILE "in.txt"
#define OUT_FILE "out.txt"

#define DATA_SIZE 9*14
#define SUM 2894

#ifdef Compiler_C
typedef enum{false, true} bool;
#endif

typedef enum{open, append, close} option;
typedef struct
{
    bool flag;
    int pos;
}feas;        //可解标志 判断对于指定值在某个位置之后是否存在可行解 
 
int g_dat[DATA_SIZE];
int g_cum[DATA_SIZE];
int g_res[DATA_SIZE];
feas g_midres[SUM+1];

void input(void);
void init(void);
void output(option outmode, int num);
bool solve(int sum, int datpos, int respos);

int main()
{
    input();
    init();
    output(open, 0);
    if(solve(SUM, 0, 0))
        printf("\rAll cases are tried and at most one solution is found.\n");
    else
        printf("\rAll cases are tried and none solution is found.\n");
    output(close, 0);

    return 0;
}

void input(void)
{
    int i;
    FILE *fp;
     
    if((fp=fopen(IN_FILE, "r")) == NULL){
        printf("Open file %s failed!\n", IN_FILE);
        exit(1);
    }

    for(i = 0; i < DATA_SIZE; i++)
        fscanf(fp, "%d", g_dat+i);
    
    fclose(fp);
}

static int cmp_lt(const void *p1, const void *p2)
{
    return (*(int*)p2 - *(int*)p1);
}

void init(void)
{
    int i;
    
    qsort(g_dat, DATA_SIZE, sizeof(int), cmp_lt);
    
    g_cum[DATA_SIZE-1] = g_dat[DATA_SIZE-1];
    for(i = DATA_SIZE-2; i >= 0; i--)
        g_cum[i] = g_cum[i+1] + g_dat[i]; 
        
    for(i = 0; i < SUM+1; i++)
        g_midres[i].flag = true;    
} 

void output(option outmode, int num)
{
    int i;
    static FILE *fp;
    static int cnt = 0;
    
    switch(outmode){
        case open:
            goto pro_open;
        case append:
            goto pro_append;
        case close:
            goto pro_close;
        default:
            return;
    }

pro_open:
    if((fp=fopen(OUT_FILE, "w"))==NULL){
        printf("Open file %s failed!\n", OUT_FILE);
        exit(1);
    }
    fprintf(fp, "[ORDER]\t[Feasible Solutions(sum is %d)]\n", SUM);
    return;

pro_append:
    fprintf(fp, " %05d\t ", ++cnt);    
    for(i = 0; i < num; i++)
        fprintf(fp, "%4d\t", g_res[i]);        
    fprintf(fp, "\n");
    
    #ifdef Display_ON
    printf("\rORDER %d: ", cnt);
    for(i = 0; i < num; i++)
        printf("%4d ", g_res[i]);        
    printf("\n");
    for(i = 0; i < num; i++)
        printf("%4d ", g_res[i]);
    #endif
    
    return;
    
pro_close:
    fclose(fp);
    return;
}

static int next(int pos, int val)
{
    while(pos<DATA_SIZE && g_dat[pos]>val)
        pos++;
    
    return pos;
}

bool solve(int sum, int datpos, int respos)
{
    bool is_solved;
    int nextpos;
    
    if(sum == 0){
        if(respos == 0)
            return false;
            
        output(append, respos);
        return true;
    }    
    else if(sum <= g_cum[datpos]){
        is_solved = false;
        nextpos = next(datpos, sum);
        while(nextpos < DATA_SIZE){
            #ifdef Display_ON
            printf("%4d ", g_dat[nextpos]);
            #endif
            
            g_res[respos] = g_dat[nextpos];
            if(g_midres[sum-g_dat[nextpos]].flag ||
               g_midres[sum-g_dat[nextpos]].pos > nextpos+1){
                   if(solve(sum-g_dat[nextpos], nextpos+1, respos+1)){
                       is_solved = true;
                   }
                   else{
                       g_midres[sum-g_dat[nextpos]].flag = false;
                       g_midres[sum-g_dat[nextpos]].pos = nextpos+1;
                   }
               }
               
               #ifdef Display_ON
            printf("\b\b\b\b\b");
            #endif
            
            while(nextpos<DATA_SIZE && g_dat[nextpos]==g_res[respos])
                nextpos = next(nextpos+1, sum);
        }
        return is_solved;
    }
    else return false; 
}

人生是一场错过 愿你别蹉跎
2013-04-05 19:41
qunxingw
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:贵宾
威 望:24
帖 子:1676
专家分:7295
注 册:2011-6-30
收藏
得分:0 
好难,顶一下,为了保障有一个解,可改为最接近2894

www.qunxingw.wang
2013-04-06 10:12
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
以下是引用qunxingw在2013-4-6 10:12:47的发言:

好难,顶一下,为了保障有一个解,可改为最接近2894

这样难度上升一个等级,额


[fly]存在即是合理[/fly]
2013-04-06 10:54
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
呵呵,别费劲了,那些数字再怎么加也加不出2894的。

原因,所有的数都是3的倍数,而2894却不能被3整除,所以无解

重剑无锋,大巧不工
2013-04-06 13:19
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 


[fly]存在即是合理[/fly]
2013-04-06 16:07
nuistkevin
Rank: 2
等 级:论坛游民
帖 子:17
专家分:10
注 册:2013-4-15
收藏
得分:0 
猎头职位-软件工程师
岗位职责
1.与世界顶尖的软件工程师共同开发虚拟化云计算产品
2.能独立处理和解决所负责的任务;
3.进行程序单元、功能的测试,查出软件存在的缺陷并保证其质量。
任职资格
1、 211或985高校计算机科学与技术或软件专业,英文流利;
2、 具有很强的学习能力和解决问题的能力;
3、 至少3年以上软件开发经验,精通C语言/C++,热衷于技术专研;
4、 熟练的数据结构知识体系与较强的算法能力,对堆栈、2X树、多X树有一定了解
5、 熟悉Windows, Linux X86/64 操作系统;
6、 熟悉Network configurations and environments;

工作地点:上海
有意者可以发送您的中英文简历至邮箱:
junpingwu@
QQ:2571168815
2013-04-15 12:00
helloUJS
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:168
专家分:731
注 册:2013-3-27
收藏
得分:0 
实际上就是求如下方程的整数解(0到9):
99*x1 + 3*x2 + 351*x + 3165*x4 +  54*x5 +  297*x6 +  9*x7 + 1053*x8  + 495*x9  + 162*x10 +  126*x11 + 75*x12 + 378*x13 + 225*x14 = 2894

[ 本帖最后由 helloUJS 于 2013-5-4 08:59 编辑 ]
2013-05-04 08:58
成欢欢
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2013-4-16
收藏
得分:0 
好难,上面那些程序好难看懂
2013-05-04 20:37
快速回复:算数问题,求算法
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.021010 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved