当前位置:   article > 正文

蓝桥杯 算法训练 粘木棍_蓝桥杯算法训练 c语言 粘木棍

蓝桥杯算法训练 c语言 粘木棍

蓝桥杯 算法训练 粘木棍

题目描述

  • 资源限制
    时间限制:1.0s 内存限制:256.0MB
  • 问题描述
    有N根木棍,需要将其粘贴成M个长木棍,使得最长的和最短的的差距最小。
  • 输入格式
    第一行两个整数N,M。
    一行N个整数,表示木棍的长度。
  • 输出格式
    一行一个整数,表示最小的差距
  • 样例输入
    3 2
    10 20 40
  • 样例输出
    10
  • 数据规模和约定
    N, M<=7

方案1 递归 枚举

#include<iostream>
#include<cmath>

using namespace std;

int n;				//n个木棍 
int m;				//粘贴成m个长木棍
int sticks[7];		//sticks[i]: 第i+1个木棍长度 
int long_sticks[7];	//long_sticks: 第i+1个长木棍的长度 
int MIN;			//最短的长木棍长度 
int MAX; 			//最长的长木棍长度 
int ans=-1; 		//最小的差距


//函数功能:    求当前位置cur 上的木棍应该粘贴在哪根长木棍上 
void f(int cur, int n, int m, int sticks[], int long_sticks[], int MAX){
	//全部分完 
	if(cur == n){
		MIN = 0;
		//判断是否有长木棍长度为0 , 若没有找出最短的长木棍 
		for(int i=0; i<m; i++){
			//长木棍长度为0  ,  不合题意 
			if(long_sticks[i]==0){
				return ;
			}else{
				if(MIN!=0){
					MIN = min(MIN, long_sticks[i]);
				}else{
					MIN = long_sticks[i];
				}
			}
		}
		//更新 最小的差距
		if(ans!=-1){
			ans = min(ans, (MAX-MIN));
		}else{
			ans = (MAX-MIN);
		}
		return ;
	}
	
	//没有分完   遍历当前位置cur 上的木棍粘贴在第i根长木棍上 
	for(int i=0; i<m; i++){
		long_sticks[i] += sticks[cur];			//长木棍长度增加 
		f(cur+1, n, m, sticks, long_sticks, max(MAX, long_sticks[i]));		//处理下一位置的木棍 
		long_sticks[i] -= sticks[cur];			//恢复现场 
	}
}


int main(){	
	cin>>n>>m;

	for(int i=0; i<n; i++){
		cin >> sticks[i];
	} 

	f(0, n, m, sticks, long_sticks, MAX);
	
	cout<<ans<<endl;

	return 0; 
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

方案2 递归 合并 (避免了大量不符题意的重复计算)

#include<iostream>
#include<cmath>

using namespace std;

int n;				//n个木棍 
int m;				//粘贴成m个长木棍
int sticks[7];		//sticks[i]: 第i+1个木棍长度 
int MIN;			//最短的长木棍长度 
int MAX; 			//最长的长木棍长度 
int ans=-1; 		//最小的差距


//函数功能:  有n个木棍,两两合并成m根, 求最小的差距 
void f(int n, int m, int sticks[]){
	//全部合并完 
	if(n == m){
		MAX = sticks[0];
		MIN = sticks[0];
		//找出最短的木棍 
		for(int i=1; i<m; i++){
			MIN = min(MIN, sticks[i]);
			MAX = max(MAX, sticks[i]);
		}
		
		//更新 最小的差距
		if(ans!=-1){
			ans = min(ans, (MAX-MIN));
		}else{
			ans = (MAX-MIN);
		}
		return ;
	}
	
	//没有合并完   将第i根木棍粘贴在第j根长木棍上 
	for(int i=0; i<n-1; i++){
		for(int j=i+1; j<n; j++){
			//记录i位置的木棍长度,便于恢复现场 
			int temp = sticks[i];
			
			//开始合并 
			sticks[j] += sticks[i];
			sticks[i] = sticks[n-1];
			
			f(n-1, m, sticks);
			
			//恢复现场 
			sticks[i] = temp;
			sticks[j] -= sticks[i];
		}
	}
}


int main(){	
	cin>>n>>m;

	for(int i=0; i<n; i++){
		cin >> sticks[i];
	} 

	f(n, m, sticks);
	
	cout<<ans<<endl;

	return 0; 
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/402718
推荐阅读
相关标签
  

闽ICP备14008679号