鱼C论坛

 找回密码
 立即注册
查看: 2713|回复: 13

C语言求助

[复制链接]
发表于 2021-12-8 01:07:02 | 显示全部楼层 |阅读模式
10鱼币
问题:如何求1到n中1个数相加,2个数相加,3个数相加……n个数相加的所有情况。给思路,方法就可以,有代码的话最好,代码最好用c,c++看不懂。求求了孩子头都秃了

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-8 16:38:16 | 显示全部楼层

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-8 16:39:49 | 显示全部楼层

有序还是无序的?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-8 20:35:31 | 显示全部楼层
我的思路是这样的,不用每次都把值算出来,结果要的是所有情况只需求出取值范围就可以了,比如123456789这9个数字中,1个数相加的情况是1到9,2个数相加的情况是2到18,等等,由此就得到n个数相加的范围为n到n的平方(有重复的情况下)。在不重复的情况下就是最小值为前n个数相加,最大值为后n个数相加。
有重复:
void sum(int n,int m)//输入相加数的总数,有多少个数相加
{
int i=0;
for(i=m;i<=m*n;i++)
{
printf("%d",i);
}
}
没有重复的麻烦点:求最大值和最小值,然后依次打印出来就可以了
int min(int m)//多少个数相加,列如10个数中3个相加,m就等于3
{
int i=1,sum=0;
for(i=1;i<=m;i++)
{
sum=sum+i;
}
return sum;
}
int max(int n;int m)//n代表总数,m和上面m一样
{
int i=0,sum=0;
for(i=1;i<=m;i++)
{
sum=sum+n;//也可以采取n平方减去m-1来求最大值
n=n-1;
}
return sum;
void result(int n;int m)//m,n同上
{
int i=min(m);
int j=max(n,m);
for(i;i<=j;i++)
{
printf("%d",i);
}
}
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-8 21:38:07 | 显示全部楼层
请问有例子吗?题目不够清晰:

1.)如何 1 个数相加?(相加不是最少 2 个数吗?)
2.)题目要求 1 到 n 中 1 个数相加,2 个数相加,3 个数相加… n 个 数相加的所有情况(所有情况是什么情况?之和呢?还是积?)
3.)n 的极限呢?20?300?100000?(这点很重要,不然代码容易超时)

看似如此简单题目,居然没有几位大佬给答案,就知道问问题方法该改一改
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-12-9 00:07:49 | 显示全部楼层
傻眼貓咪 发表于 2021-12-8 21:38
请问有例子吗?题目不够清晰:

1.)如何 1 个数相加?(相加不是最少 2 个数吗?)

一个数相加就当做他本身,比如说1-5  先是一个数相加1.2.3.4.5然后是两个数相加 1+2  1+3 1+4 1+5 2+3 +2+4 2+5 3+4 3+5 4+5 三个数相加1+2+3 1+2+4 1+2+5 2+3+4 2+3+5 3+4+5然后四个数 五个数...
我是想学一下这种穷举法怎么用代码实现 原题我放楼下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-12-9 00:10:57 | 显示全部楼层
本帖最后由 卷不动 于 2021-12-9 00:13 编辑

考虑将正整数n拆分成几个不同的平方数之和,比如30=1^2 + 2^2 + 5^2=1^2 + 2^2 + 3^2 + 4^2,而8不存在这样的拆分。 用k(n)表示n的拆分中,最大的底数最小可能是多少。如果n不存在这样的拆分,则令k(n)=∞。例如,k(1)=1,k(8)=∞,k(378)=12,k(380)=10。 定义一个数x被称为“超重”的,当且仅当存在y>x,使得k(y)<k(x)。从上面的例子可知,378是一个“超重”的数。
给定n,你需要:(1)求出k(n)(2)求出1~n中有几个“超重”的数。输入格式输入仅一行,包含一个正整数n(1<=n<=10^18)。输出格式输出一行包含两个整数,分别为对上述两个问题的答案。如果k(n)=∞,则输出一个减号'-'代替。
输入输出样例
输入 30
输出 4 15
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-9 00:36:13 From FishC Mobile | 显示全部楼层
这题没有这么简单,难点在于:

1.)极限 n <= 10^18(只能用最大容量的 unsigned long long)代码必须超级精简,否则超时
2.)函数返回值有可能出现无限(如:k(8) = 无限)在程序代码是不允许的,必须深入了解其数学原理,附加条件,才能保持代码通顺。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-12-9 08:24:11 | 显示全部楼层
傻眼貓咪 发表于 2021-12-9 00:36
这题没有这么简单,难点在于:

1.)极限 n

题上说无穷大用'-'代替。.....我想用穷举出所有加法的情况  但是不知道怎么用代码实现。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-12-9 08:44:55 | 显示全部楼层
派大星不呆 发表于 2021-12-8 20:35
我的思路是这样的,不用每次都把值算出来,结果要的是所有情况只需求出取值范围就可以了,比如123456789这9 ...

谢谢大佬,思路很nice,但是这个思路还是没法解决我的问题....
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-19 14:38:31 | 显示全部楼层
1加到n
#include<stdio.h>
int main(){
        int i,n,sum=0;
        scanf("%d",&n);
        for(i=1;i<=n;i++){
                sum+=i;
        }
        printf("%d",sum);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-19 19:12:56 | 显示全部楼层
本帖最后由 人造人 于 2022-2-19 19:14 编辑
卷不动 发表于 2021-12-9 00:07
一个数相加就当做他本身,比如说1-5  先是一个数相加1.2.3.4.5然后是两个数相加 1+2  1+3 1+4 1+5 2+3 +2 ...

$ cat main.c
#include <stdio.h>

void calc(const size_t data[], size_t size) {
    const char *sep = "";
    size_t sum = 0;
    for(size_t i = 0; i < size; ++i) {
        sum += data[i];
        printf("%s%lu ", sep, data[i]);
        sep = "+ ";
    }
    printf("= %lu\n", sum);
}

void enum_all(const size_t data[], size_t size, size_t buff[], size_t index, size_t count) {
    if(index >= count) {
        calc(buff, index);
        return;
    }
    if(size == 0) return;
    for(size_t i = 0; i < size; ++i) {
        buff[index] = data[i];
        enum_all(data + 1 + i, size - 1 - i, buff, index + 1, count);
    }
}

int main(void) {
    size_t data[] = {1, 2, 3, 4, 5};
    size_t buff[5];
    for(size_t i = 0; i < 5; ++i) {
        enum_all(data, 5, buff, 0, i + 1);
    }
    //enum_all(data, 5, buff, 0, 3);
    //enum_all(data, 5, buff, 0, 2);
    return 0;
}
$ gcc-debug -o main main.c
$ ./main
1 = 1
2 = 2
3 = 3
4 = 4
5 = 5
1 + 2 = 3
1 + 3 = 4
1 + 4 = 5
1 + 5 = 6
2 + 3 = 5
2 + 4 = 6
2 + 5 = 7
3 + 4 = 7
3 + 5 = 8
4 + 5 = 9
1 + 2 + 3 = 6
1 + 2 + 4 = 7
1 + 2 + 5 = 8
1 + 3 + 4 = 8
1 + 3 + 5 = 9
1 + 4 + 5 = 10
2 + 3 + 4 = 9
2 + 3 + 5 = 10
2 + 4 + 5 = 11
3 + 4 + 5 = 12
1 + 2 + 3 + 4 = 10
1 + 2 + 3 + 5 = 11
1 + 2 + 4 + 5 = 12
1 + 3 + 4 + 5 = 13
2 + 3 + 4 + 5 = 14
1 + 2 + 3 + 4 + 5 = 15
$
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-20 09:22:40 | 显示全部楼层
学习来了


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-20 22:58:46 | 显示全部楼层
我个人理解是这样的:n个数中取1,2,3,...,n个数相加的情况类似于数学上的组合数。
取k个数相加就是组合数Cnk,这样能简单的算出k个数时所有的情况。另外,根据二项式系数和可知共有2^n种情况。
再简单分析一下,如果将1到n排列为一个数组,参与相加的标记为1,未参与的标记0,那么所有标记都会组成n位的二进制数,每一个数都代表一种情况(事实上n位二进制数可表示2^n种,这与二项式系数和不谋而合)
至于代码实现部分比较简单,组合数的计算也只是涉及到阶乘,难度并不大。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-18 12:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表