CSDN论坛99%的人不会写的程序.

sunrier 2019-11-26 10:48:12
有N个数(整数,可以重复),从N个数里取M个数,使得取出的M(1<=M<=N)个数和为SUM,并输出对应的索引
如N=15个数
8,9,3,1,6,18,5,3,15,99,9,18,1000,15,500
SUM=15

此时输出
M=1
8,13

M=2
1-4,4-10

M=3
0-3-4

有谁有兴趣实现这个功能,用C语言,不带有容器的函数.
...全文
3277 121 打赏 收藏 转发到动态 举报
写回复
用AI写文章
121 条回复
切换为时间正序
请发表友善的回复…
发表回复
dume_c 2020-01-13
  • 打赏
  • 举报
回复
很好,我是99%之一
qq_20903015 2020-01-12
  • 打赏
  • 举报
回复
我想下载,这么下载固件
  • 打赏
  • 举报
回复
大神表示没看懂,小白你出来讲一下题目
sunrier 2020-01-06
  • 打赏
  • 举报
回复
继续
轩墨宝宝SR 2019-12-12
  • 打赏
  • 举报
回复
你要是老老实实问题,应该会有更多人回答你的问题
sunrier 2019-12-11
  • 打赏
  • 举报
回复
引用 119 楼 早打大打打核战争 的回复:
没可能,不要说10000个数,32个数(假设都小于SUM),如果不是数据有特殊分布的话(比如有很多0、1之类的小数据),5秒都不可能

所以要解决那些不可能.
权超勤 2019-12-05
  • 打赏
  • 举报
回复
只用了List集合呀,感觉能实现就已经很难了,我这种半年没到的老鸟能写出来已经不容易了,也考虑不到效率,数据结构时间复杂度最近在看,只是入门水平
sheonyang 2019-12-04
  • 打赏
  • 举报
回复
20分 帮你写作业 真可
sunrier 2019-12-04
  • 打赏
  • 举报
回复
引用 91 楼 离水的鱼儿 的回复:
[quote=引用 90 楼 早打大打打核战争 的回复:][quote=引用 79 楼 SuperDay 的回复:]
[quote=引用 70 楼 早打大打打核战争的回复:][quote=引用 63 楼 u013962723 的回复:]
钓鱼帖?只有20分,钓鱼无误
如果说N,M数据量大那还好说,比如N和M是10^5这个级别的,或者说取多组M个数,满足和为SUM。
不然嘛,高中生水平的算法,哪儿那么多底气?


就是多组,他这题是求N个数,C(N, 1)..C(N, N)中所有和为SUM的组合,实际是一维装箱问题,不要说N是10^5这个级别,超过48个数用PC都不容易在有效时间内解决。
[/quote]
应该是2^N-1个组合,2^48应该是以年为单位的CPU时间了[/quote]

多核优化一下,现在的PC应该能在30秒内解出32个数的穷举,换算成48个数大概要三周,如果是32核64线程的线程撕裂者,有可能3天时间解决问题,还算可以。
这题可能优化的地方就是先预处理一下数据,如果都是正数,把大于SUM的数都删掉。
[/quote]老铁说的有道理,你的一句话点醒了许多人。
先去掉不合法的数据大大提高性能呀。[/quote]

假设50个数都是合法的数据如何解决呢?
sunrier 2019-12-04
  • 打赏
  • 举报
回复
引用 111 楼 weixin_43163290 的回复:
JAVA 我就是那百分之一

package com.study;

import java.util.*;

/**
* @description: 求和
* @author: quan
* @create: 2019/11/29 13:42
**/
public class Main {
//和
private static int sum;
//数据规模
private static int size=1000;
//两两相加节点集合
private static List<Node> templist=new ArrayList<>();
//根节点
private static List<Node> listone=new ArrayList<>();
//记录每次相加的结果 去重复
private static List<String> results=new ArrayList<>();
private static List<Integer> result=new ArrayList<>();
//状态
private static boolean flag=true;
public static void main(String[] args) {
System.out.println("输入:");
List<Node> list = scanner();
Scanner scanner = new Scanner(System.in);
System.out.println("输入和:");
sum = scanner.nextInt();

//M
for (int m = 0; m < size; m++) {

//两两相加如果符合条件下下遍历下标
for (int i = 0; i < list.size(); i++){
Node node1 = list.get(i);
//找出直接满足条件的下标并输出(第一次)
if(m==0){
if (node1.getData() == sum) {
System.err.println("M="+(m+1)+":下标:" + node1.getId() + ",数据:" + node1.getData()+"\n");
}
}
else {

for (int j = 0; j < size; j++) {
//单节点
Node node2 = listone.get(j);
//临时
Node temp = new Node(node1, node2);
foreach(node1,node2.getId(),result);
result.add(node2.getId());
Collections.sort(result);
if(flag==true){
templist.add(temp);
//达成条件
if (temp.getData() == sum){
//存放
//遍历输出
if (result.size() > 0) {
String str="M=" + (m + 1) + ":";
for (int id : result) {
str+="下标:" + id + ",数据:" + listone.get(id).getData() + "\t";
}
boolean flag=true;
for(String res:results){
if(res.equals(str)){
flag=false;
}
}
if(flag==true) {
System.err.println(str);
results.add(str);
}
}

System.err.println();
}
}
flag=true;
result.clear();

}
}
}
results.clear();
if(m!=0) {
list.clear();
for(Node node:templist){
list.add(node);
}
templist=new ArrayList<>();
}
}
}

public static void foreach(Node node,int id,List<Integer> result){
//如果不是根节点
if(node.getNode1()!=null){
foreach(node.getNode1(),id,result);
if(node.getNode2()!=null){
foreach(node.getNode2(),id,result);
}
}else {
//进入根节点
if(node.getId()==id){
result.clear();
flag=false;
return;
}
result.add(node.getId());
}

}
public static List<Node> scanner(){
List<Node> list=new ArrayList<>();
Scanner scanner = new Scanner(System.in);
int count=0;
while(scanner.hasNextInt()){
int a=scanner.nextInt();
Node temp = new Node();
temp.setId(count);
temp.setData(a);
listone.add(temp);
list.add(temp);
count++;

}
size=list.size();
return list;
}
public static List init(){
List<Node> list=new ArrayList<>();
Random random=new Random();
for(int i=0;i<size;i++){
Node node=new Node(i,random.nextInt(1000));
list.add(node);
listone.add(node);
}
return list;
}
}
//节点类
package com.study;

/**
* @description: 节点
* @author: quan
* @create: 2019/11/29 14:16
**/
public class Node {
private int id=0;
private int data;
private Node node1;
private Node node2;

public Node getNode1() {
return node1;
}

public Node(Node node1, Node node2) {
this.node1 = node1;
this.node2 = node2;
data=node1.data+node2.data;
}

public Node getNode2() {
return node2;
}

public void setNode1(Node node1) {
this.node1 = node1;
}

public void setNode2(Node node2) {
this.node2 = node2;
}

public void setId(int id) {
this.id = id;
}

public void setData(int data) {
this.data = data;
}

public int getId() {
return id;
}

public int getData() {
return data;
}
public Node(){

}
public Node(int id, int data) {
this.id = id;
this.data = data;
}
}

你不用容器,能自己写出来吗?不过还是要赞一下.
  • 打赏
  • 举报
回复
没可能,不要说10000个数,32个数(假设都小于SUM),如果不是数据有特殊分布的话(比如有很多0、1之类的小数据),5秒都不可能
sunrier 2019-12-04
  • 打赏
  • 举报
回复
此题目对于大数据,如N=10000,所有数据都是小于SUM的,
有谁能对算法做最大的优化?如10000个数据控制在5秒内.
洪水相逢 2019-12-04
  • 打赏
  • 举报
回复
强制冷静  坚韧   理性 你无法激怒我
s0611163 2019-12-03
  • 打赏
  • 举报
回复
不值得烧脑子
发记 2019-12-03
  • 打赏
  • 举报
回复
每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!每天回帖即可获得10分可用分!
权超勤 2019-12-03
  • 打赏
  • 举报
回复
JAVA 我就是那百分之一 package com.study; import java.util.*; /** * @description: 求和 * @author: quan * @create: 2019/11/29 13:42 **/ public class Main { //和 private static int sum; //数据规模 private static int size=1000; //两两相加节点集合 private static List<Node> templist=new ArrayList<>(); //根节点 private static List<Node> listone=new ArrayList<>(); //记录每次相加的结果 去重复 private static List<String> results=new ArrayList<>(); private static List<Integer> result=new ArrayList<>(); //状态 private static boolean flag=true; public static void main(String[] args) { System.out.println("输入:"); List<Node> list = scanner(); Scanner scanner = new Scanner(System.in); System.out.println("输入和:"); sum = scanner.nextInt(); //M for (int m = 0; m < size; m++) { //两两相加如果符合条件下下遍历下标 for (int i = 0; i < list.size(); i++){ Node node1 = list.get(i); //找出直接满足条件的下标并输出(第一次) if(m==0){ if (node1.getData() == sum) { System.err.println("M="+(m+1)+":下标:" + node1.getId() + ",数据:" + node1.getData()+"\n"); } } else { for (int j = 0; j < size; j++) { //单节点 Node node2 = listone.get(j); //临时 Node temp = new Node(node1, node2); foreach(node1,node2.getId(),result); result.add(node2.getId()); Collections.sort(result); if(flag==true){ templist.add(temp); //达成条件 if (temp.getData() == sum){ //存放 //遍历输出 if (result.size() > 0) { String str="M=" + (m + 1) + ":"; for (int id : result) { str+="下标:" + id + ",数据:" + listone.get(id).getData() + "\t"; } boolean flag=true; for(String res:results){ if(res.equals(str)){ flag=false; } } if(flag==true) { System.err.println(str); results.add(str); } } System.err.println(); } } flag=true; result.clear(); } } } results.clear(); if(m!=0) { list.clear(); for(Node node:templist){ list.add(node); } templist=new ArrayList<>(); } } } public static void foreach(Node node,int id,List<Integer> result){ //如果不是根节点 if(node.getNode1()!=null){ foreach(node.getNode1(),id,result); if(node.getNode2()!=null){ foreach(node.getNode2(),id,result); } }else { //进入根节点 if(node.getId()==id){ result.clear(); flag=false; return; } result.add(node.getId()); } } public static List<Node> scanner(){ List<Node> list=new ArrayList<>(); Scanner scanner = new Scanner(System.in); int count=0; while(scanner.hasNextInt()){ int a=scanner.nextInt(); Node temp = new Node(); temp.setId(count); temp.setData(a); listone.add(temp); list.add(temp); count++; } size=list.size(); return list; } public static List init(){ List<Node> list=new ArrayList<>(); Random random=new Random(); for(int i=0;i<size;i++){ Node node=new Node(i,random.nextInt(1000)); list.add(node); listone.add(node); } return list; } } //节点类 package com.study; /** * @description: 节点 * @author: quan * @create: 2019/11/29 14:16 **/ public class Node { private int id=0; private int data; private Node node1; private Node node2; public Node getNode1() { return node1; } public Node(Node node1, Node node2) { this.node1 = node1; this.node2 = node2; data=node1.data+node2.data; } public Node getNode2() { return node2; } public void setNode1(Node node1) { this.node1 = node1; } public void setNode2(Node node2) { this.node2 = node2; } public void setId(int id) { this.id = id; } public void setData(int data) { this.data = data; } public int getId() { return id; } public int getData() { return data; } public Node(){ } public Node(int id, int data) { this.id = id; this.data = data; } }
发记 2019-12-03
  • 打赏
  • 举报
回复
非常好,真的很喜欢你的内容,崇拜你
xiaoxiangqing 2019-12-03
  • 打赏
  • 举报
回复
不考虑性能的话,应该不算太难
最帅的逆行 2019-12-02
  • 打赏
  • 举报
回复
回复一下,看能不能混一点C币
hwyqy 2019-12-02
  • 打赏
  • 举报
回复
这个题目有这么难么,虽然你是11年的老鸟,可我是01年的老鸟 好吧,我承认我不会
加载更多回复(101)

69,375

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧