问题描述

乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位。然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。请你设计一个程序,帮助乔治计算木棒的可能最小长度。每一节木棍的长度都用大于零的整数表示。

输入格式   输入包含多组数据,每组数据包括两行。第一行是一个不超过64的整数,表示砍断之后共有多少节木棍。第二行是截断以后,所得到的各节木棍的长度。在最后一组数据之后,是一个零。

输出格式   为每组数据,分别输出原始木棒的可能最小长度,每组数据占一行。

样例输入 9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0

样例输出 5 6

算法思路

通过问题描述可以初步得知,木棒的最小可能长度至少要大于木棒长度序列中的最大值且一定能被木棒长度序列之和整除。因此我们就可以我们就可以在这两个上下界之间,通过深度搜索的方式不断的试探每一个可能的最小长度,若试探成功则该长度即为木棒的最小可能长度,若失败则进行下一个可能的长度进行试探,直至成功。算法参考于这位大佬

程序如下

import java.util.Scanner;

public class Main{

public static int g;//每组拼接完毕后,所拼接好的木棒数

public static int len;//每组满足要求的拼接后的木棒的长度,每组木棒总长度 = g * len;

/*

深度搜索

a:每组木棒的长度数组

visited:为数组中每一个木棒长度设置一个访问标志,默认初值为0

n:表示每组木棒数组的长度

nowlen:表示当前已拼接成的木棒的长度

nowget:表示现在拼接成的木棒的总数,当nowGet = g时找到符合要求的木棒长

cnt:拼接过程中查找剩下符合要求的木棒应该从哪个下标开始查找

*/

public static boolean dfs(int[] a,int[] visited,int n,int nowlen,int nowget,int cnt){

if(cnt >= n) return false; //下标超过木棒总数n时,显然不满足

if(nowget == g) return true;//当前长度下获取的总个数与g相等说明符合条件

//开始遍历查找

for (int i = cnt; i < n; i++) {

//访问没有被用过的木棒

if(visited[i] == 0){

//当加入当前的木棒后,恰好能拼接成需要的长度时

if(nowlen + a[i] == len){

visited[i] = 1;//标记当前木棒已被使用

//在此组满足后,进行下一组的寻找,此时下一组的nowlen=0,nowget=nowget+1;

if(dfs(a,visited,n,0,nowget+1,nowget)){

//递归,直到最后一组都满足需要的长度时说明查找成功

return true;

}

//查找失败,说明此木棒不可选

visited[i] = 0;//将visited重新置为0,进行回溯

return false;

}

//当找到的一组木棒还小于拼接成需要的长度时

if(nowlen + a[i] < len){

visited[i] = 1;//标记当前木棒已被使用

//接着递归,查找下一个,即从i的下一个i+1开始

if(dfs(a,visited,n,nowlen+a[i],nowget,i+1)){

//在当前满足的基础上,依次向后递归

return true;//查找成功

}

//查找失败

visited[i] = 0;//回溯

//剪枝,在当前搜索时,前面长度为0,并且第一根没有被成功使用,说明第一跟始终要被放弃的,所以这种组合不会成功

if(nowlen == 0) return false;

//如果有一根木棒加上去已经知道不满足要求,则与它同长度的木棒都可以跳过

for ( ;a[i] == a[i+1] && i + 1 < n;i++);

}

}

}

return false;

}

//冒泡排序,顺序:由大到小

public static void sort(int[] arr,int num){

int temp;

for (int i = 0; i < num-1; i++) {

for (int j = i+1; j < num; j++) {

if(arr[i] < arr[j]){

temp = arr[i];

arr[i] = arr[j];

arr[j] = temp;

}

}

}

}

public static void main(String[] args) {

Scanner input = new Scanner(System.in);

int[][] maxti = new int[100][100];//用于存储输入每组木棒的长度

int[] sumArr = new int[100];//用于存储每组木棒的总长度

int[] eachCounts = new int[100];//用于存储每组木棒的数量

int[] a = new int[100];//用与存储每组木棒的长度序列

int n;//每组木棒总数

//用户输入每组的木棒数

int inc = 0;//设置自增变量,便于去二维数组maxti中取值

int sum;//用于计算每组木棒总长的中间变量

while(true){

n = input.nextInt();//每组木棒的总个数

eachCounts[inc] = n;

if(n == 0){//输入为0时,结束输入

break;

}

sum = 0;

for (int i = 0; i < n; i++) {

maxti[inc][i] = input.nextInt();//二维数组maxti的每一行表示一组数据

sum += maxti[inc][i];

}

sumArr[inc] = sum;//存储每一组数据的总和

inc++;

}

//对输入的每组木棒序列进行递归搜索

for (int i = 0; i < inc; i++) {//对二维数组一行一行访问

int[] visited = new int[100];//设置每组木棒的访问标志量

for (int j = 0; j < eachCounts[i]; j++) {

a[j] = maxti[i][j];

}

//a = maxti[i];

sort(a,eachCounts[i]);//从大到小排序得到的序列,a[0]显然是序列中的最大值

for (len = a[0];len <= sumArr[i];len++) {//对原木棒可能的长度进行遍历查找

if(sumArr[i] % len != 0) continue;//有题意可知,最后选的木棒长度一定是能被总木棒长度整除的

g = sumArr[i] / len;//拼接后的木棒数

//剪枝,满足要求退出循环

if(dfs(a,visited,eachCounts[i],0,0,0)){

break;

}

}

//输出满足要求得木棒长

System.out.println(len);

}

}

}

java折木棍_蓝桥杯算法训练 Sticks(木棍)问题(JAVA)相关推荐

  1. 蓝桥杯算法训练sticks

    持续更新蓝桥杯算法训练题解,有兴趣可以关注一波呀. 文章目录 题目 题解 数据传送阵 代码传送阵 题目 George took sticks of the same length and cut th ...

  2. 蓝桥杯java最小公倍数_蓝桥杯算法训练 最大最小公倍数

    问题描述 已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少. 输入格式 输入一个正整数N. 输出格式 输出一个整数,表示你找到的最小公倍数. 样例输入 9 样例输出 504 ...

  3. 蓝桥杯 算法训练试题 数据交换 Java

    题目详情 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 编写一个程序,输入两个整数,分别存放在变量x和y当中,然后使用自己定义的函数swap来交换这两个变量的值. 输入格式:输入只 ...

  4. 蓝桥杯算法训练—粘木棍

    资源限制 内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s 问题描述 有N根木棍,需要将其粘贴成M个长木棍,使得最长的和最短的的差距最 ...

  5. 蓝桥杯 算法训练 粘木棍

    问题描述 有N根木棍,需要将其粘贴成M个长木棍,使得最长的和最短的的差距最小. 输入格式 第一行两个整数N,M. 一行N个整数,表示木棍的长度. 输出格式 一行一个整数,表示最小的差距 样例输入 3 ...

  6. 蓝桥杯算法训练 瓷砖铺放JAVA

    问题描述 有一长度为N(1<=N<=10)的地板,给定两种不同瓷砖:一种长度为1,另一种长度为2,数目不限.要将这个长度为N的地板铺满,一共有多少种不同的铺法? 例如,长度为4的地面一共有 ...

  7. python语言单词接龙_[蓝桥杯][算法训练VIP]单词接龙 (C语言代码)

    解题思路: 注意事项: 参考代码: #include #include #include int long_best=0,n; int * shu_zu, * zhefuc_size; char * ...

  8. 蓝桥杯 算法训练 Sticks

    资源限制 时间限制:1.0s 内存限制:999.4MB Sticks Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 113547 ...

  9. 蓝桥杯算法训练 礼物(java,个人想法,递归找临界点)

    蓝桥杯算法训练 礼物(java,个人想法,递归找临界点) 问题描述 JiaoShou在爱琳大陆的旅行完毕,即将回家,为了纪念这次旅行,他决定带回一些礼物给好朋友. 在走出了怪物森林以后,JiaoSho ...

最新文章

  1. 2019-2020-3 《Java 程序设计》第三周知识总结
  2. 过滤注入代码的存储过程
  3. 蚂蚁金服的 Service Mesh 演进之道?
  4. 10.18.1 linux文本编辑器vim
  5. java面试题二十六 多线程考题
  6. python全局变量的声明和使用_Python二级(07)——函数和代码复用
  7. java enummap_Java EnumMap containsKey()方法与示例
  8. linux-修改所有者与所属组
  9. c++图书管理系统_我用Python帮学校写了一款图书管理系统!教导员居然请我吃饭
  10. 如何用python写程序设置当前打印机为默认打印机,从Python打印到标准打印机?
  11. python 使用win32api截图全解释
  12. android10.0连接wifi后提示“已连接,但无法访问互联网”
  13. VBA变量和函数名中文拼音输入提示
  14. 为什么别人报价成单,而你不行?
  15. 天使轮,种子,A轮,B轮,C轮,Pre-IPO
  16. fsck.ext3:unable to resolve 'LABLE=/home'
  17. php接入钉钉注册回调
  18. 《2019全球货运代理TOP25、全球第三方物流Top50排行榜》
  19. 睡眠周期检测与吸引力法则
  20. SAP abap alv报表实例

热门文章

  1. 医院计算机五大应用系统,医院计算机五大应用系统
  2. QQ2012[QQ圈子]功能试用:按照真实生活将好友分圈
  3. oracle版linux查看rac ip,oracle10g RAC中查看Private IP的方法
  4. 有没有简单易懂不枯燥的Java入门教程?
  5. websocket + tls + cdn 断流严重问题解决方法
  6. 量子力学 Schrodinger 方程的简单导出
  7. 安装nodejs教程
  8. 西南知识产权大数据中心落地成都
  9. APP开发流程工作详解
  10. 计算机职业素质测评报告,人员素质测评报告书.doc