C语言求助
问题:如何求1到n中1个数相加,2个数相加,3个数相加……n个数相加的所有情况。给思路,方法就可以,有代码的话最好,代码最好用c,c++看不懂。求求了孩子头都秃了最强废铁h 发表于 2021-12-8 16:38
有序还是无序的? 我的思路是这样的,不用每次都把值算出来,结果要的是所有情况只需求出取值范围就可以了,比如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);
}
}
} 请问有例子吗?题目不够清晰:
1.)如何 1 个数相加?(相加不是最少 2 个数吗?)
2.)题目要求 1 到 n 中 1 个数相加,2 个数相加,3 个数相加… n 个 数相加的所有情况(所有情况是什么情况?之和呢?还是积?)
3.)n 的极限呢?20?300?100000?(这点很重要,不然代码容易超时)
看似如此简单题目,居然没有几位大佬给答案,就知道问问题方法该改一改 傻眼貓咪 发表于 2021-12-8 21:38
请问有例子吗?题目不够清晰:
1.)如何 1 个数相加?(相加不是最少 2 个数吗?)
一个数相加就当做他本身,比如说1-5先是一个数相加1.2.3.4.5然后是两个数相加 1+21+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然后四个数 五个数...
我是想学一下这种穷举法怎么用代码实现 原题我放楼下 本帖最后由 卷不动 于 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 这题没有这么简单,难点在于:
1.)极限 n <= 10^18(只能用最大容量的 unsigned long long)代码必须超级精简,否则超时
2.)函数返回值有可能出现无限(如:k(8) = 无限)在程序代码是不允许的,必须深入了解其数学原理,附加条件,才能保持代码通顺。 傻眼貓咪 发表于 2021-12-9 00:36
这题没有这么简单,难点在于:
1.)极限 n
题上说无穷大用'-'代替。.....我想用穷举出所有加法的情况但是不知道怎么用代码实现。 派大星不呆 发表于 2021-12-8 20:35
我的思路是这样的,不用每次都把值算出来,结果要的是所有情况只需求出取值范围就可以了,比如123456789这9 ...
谢谢大佬,思路很nice,但是这个思路还是没法解决我的问题....{:10_269:}{:10_269:} 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);
} 本帖最后由 人造人 于 2022-2-19 19:14 编辑
卷不动 发表于 2021-12-9 00:07
一个数相加就当做他本身,比如说1-5先是一个数相加1.2.3.4.5然后是两个数相加 1+21+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;
printf("%s%lu ", sep, data);
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 = data;
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;
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
$ 学习来了
我个人理解是这样的:n个数中取1,2,3,...,n个数相加的情况类似于数学上的组合数。
取k个数相加就是组合数Cnk,这样能简单的算出k个数时所有的情况。另外,根据二项式系数和可知共有2^n种情况。
再简单分析一下,如果将1到n排列为一个数组,参与相加的标记为1,未参与的标记0,那么所有标记都会组成n位的二进制数,每一个数都代表一种情况(事实上n位二进制数可表示2^n种,这与二项式系数和不谋而合)
至于代码实现部分比较简单,组合数的计算也只是涉及到阶乘,难度并不大。
页:
[1]