zoukankan      html  css  js  c++  java
  • 拆数,给定两个正整数m,n(m >= n),将m拆成n个数相加...(游戏)

    1. 问题

    (网上看到的题目)
    昨天去面试人家出了这样一道题,觉得挺简单的,但就是编不出来,只好麻烦各位高手了。
    给定两个正整数m,n(m >= n),将m拆成n个数相加:m =a(1)+a(2)+...+a(n),使之满足:a(1)<a(2)<...<a(n);
    列出所有的拆法。
    例如:若m=7,n=3则只有一种拆法:7=1+2+4。

    2. 解决代码

    package com.clzhang.game;
    
    /**
     * 问题:
     * 昨天去面试人家出了这样一道题,觉得挺简单的,但就是编不出来,只好麻烦各位高手了。
     * 给定两个正整数m,n(m >= n),将m拆成n个数相加:m =a(1)+a(2)+...+a(n),使之满足:a(1)<a(2)<...<a(n);
     * 列出所有的拆法。
     * 例如:若m=7,n=3则只有一种拆法:7=1+2+4。
     * @version 1.0
     * @author acer
     */
    import java.util.*;
    
    public class SplitInt {
    
        // 返回所有拆法中各最大数集合中的最大数
        private int getMax(int m, int n, int lastNum) {
            int total = 0;
            for (int i = 1; i < n; i++) {
                total += i;
            }
            if ((m - total) >= lastNum)
                return lastNum - 1;
            else
                return m - total;
        }
    
        // 返回当前数是否可能组成一种拆法
        private boolean isValidNum(int m, int n, int num) {
            int total = 0;
            if (num < n)
                return false;
    
            for (int i = 0; i < n; i++) {
                total += num--;
            }
            return total >= m;
        }
    
        /*
         * 计算拆分结果,递归调用 
         * @param m - 被拆数 
         * @param n - 拆分个数 
         * @param lastNum - 上一次拆分数值
         */
        public LinkedList<String> calu(int m, int n, int lastNum) {
            LinkedList<String> result = new LinkedList<String>();
            if (n == 1) {
                result.add(String.valueOf(m));
                return result;
            }
    
            int num = getMax(m, n, lastNum);
            while (isValidNum(m, n, num)) {
                LinkedList<String> lkl = calu(m - num, n - 1, num);
                for (int i = 0; i < lkl.size(); i++) {
                    result.add(String.valueOf(num) + "+" + lkl.get(i));
                }
                num--;
            }
            return result;
        }
    
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入m值:");
            int m = scanner.nextInt();
            System.out.println("请输入n值:");
            int n = scanner.nextInt();
            scanner.close();
            
            AbstractList<String> list = new SplitInt().calu(m, n, m);
            if (list.size() == 0)
                System.out.println("没有解!");
            else {
                for (int i = 0; i < list.size(); i++)
                    System.out.println("第 " + (i + 1) + " 种拆法:" + list.get(i));
            }
        }
        
    }

    3. 输出

    请输入m值:
    10
    请输入n值:
    3
    第 1 种拆法:7+2+1
    第 2 种拆法:6+3+1
    第 3 种拆法:5+4+1
    第 4 种拆法:5+3+2 

  • 相关阅读:
    ajax与302响应
    读过/在读/想读的英文原著
    从编译DotNetOpenAuth中学到的程序集强签名知识
    百度输入法引起的Mac远程桌面Ctrl+.快捷键不起作用
    MacBook鼠标指针乱窜/不受控制问题的解决方法
    IIS中User-mode caching引起的Cache-Control不为public的问题
    让IIS8支持WCF的最简单方法
    在ASP.NET Web Forms中用System.Web.Optimization取代SquishIt
    苹果官方发布,iPhone 6 & Plus 设计素材
    jQuery 特效:盒子破碎和移动动画效果
  • 原文地址:https://www.cnblogs.com/nayitian/p/2873734.html
Copyright © 2011-2022 走看看