随机数求和

SaintTinyBoy 2015-07-04 04:14:37
随机生成6个数字,数字范围在100-300之间,使得6个数字之和=1000,其中6 100-300 1000这些参数是用户设定的,算法什么思路
...全文
742 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
乐记 2015-07-09
  • 打赏
  • 举报
回复
我的方法是依次随机填充,并保证后续数在范围内

import java.util.*;


public class RandomSum {
	private int numOfNums;
	private int minR;
	private int maxR;
	private int total;
	private int[] nums;
	
	public RandomSum(int num, int min, int max, int total) {
		this.numOfNums = num;
		this.minR = min;
		this.maxR = max;
		this.total = total;
		this.nums = new int[num];
	}
	
	public int sum(int num) {
		int s = 0;
		for (int i = 0; i < num; i++) {
			s += nums[i];
		}
		return s;
	}
	
	public int[] getRandomNums() {
		int avg = total / numOfNums;
		if (avg < minR || avg > maxR) {  //如果平均数不在范围内的话,就无解
			System.out.println("No answer!");
			System.exit(1);
		}
		Random rand = new Random();
		for (int i = 1; i < numOfNums; i++) {
			do {
				nums[i - 1] = rand.nextInt(maxR - minR) + minR;//随机填充,并保证后续数能在范围内
			} while (total - sum(i) > maxR * (numOfNums - i) | total - sum(i) < minR * (numOfNums - i));
		}
		nums[numOfNums - 1] = total - sum(numOfNums - 1);
		return nums;
	}
	
	
	public static void main(String args[]) {
		Scanner keyboard = new Scanner(System.in);
		int num = keyboard.nextInt();
		int min = keyboard.nextInt();
		int max = keyboard.nextInt();
		int total = keyboard.nextInt();
		RandomSum test = new RandomSum(num, min, max, total);
		int result[] = test.getRandomNums();
		for (int n : result) {
			System.out.print(" " + n);
		}
	}
	
}
SaintTinyBoy 2015-07-09
  • 打赏
  • 举报
回复
引用 26 楼 qq118194716 的回复:
[quote=引用 25 楼 owen00sun 的回复:]

public class RandomTest {

    /*idea: example{100,200,6,1080}
    1. nums = {100,100,100,100,100,100}
    * 2.generate 6 random number,nums={178,110,120,132,160,123},leftSum = 1080-823=257,avgLeft = 257/6 =42
    * 3 nums[0]+ avgLeft :if 178 + 42 > 200,then nums[0] = 200 leftNums[0] = (178+42-200)=20  maxNumCount+1
    * if 110 + 42 < 200 nums[1] = 152 leftNums[1] = 0 finalSum += nums[i]
    * 4.nums = {200,152,162,174,200,165} ,maxNumCount = 2
    * 5.if avgLeft ==0 means no avgLeftSum is small enough, add it to the min value in nums,exit loop;else loop until finalSum == sum
    */
    private int minNum, maxNum, cnt, sum, leftSum;
    private int[] nums;
    private int[] leftNums;
    private boolean isChecked = false;

    public RandomTest(int minNum, int maxNum, int cnt, int sum) {
        this.maxNum = maxNum;
        this.minNum = minNum;
        this.cnt = cnt;
        this.sum = sum;
        nums = new int[cnt];
        leftNums = new int[cnt];
    }

    private int[] generate() throws IntegerException {
        checkMinAndMax();
        if (this.isChecked) {
            return nums;
        }
        int seed = this.maxNum - this.minNum;  //生成随机数种子
        this.leftSum = this.sum - (this.cnt * this.minNum); //获取剩余的和
        for (int i = 0; i < this.cnt; i++) {
            int number = generateInt(seed);
            nums[i] += number;
            this.leftSum -= number;
        }
        int finalSum = 0;
        int maxNumCount = 0;  //统计nums中有多少个最大值
         while (finalSum != this.sum) {
            finalSum = 0;
            if(this.cnt-maxNumCount == 0){
                break;
            }
            int avgLeft = (int) Math.floor(this.leftSum / (this.cnt-maxNumCount)); //分配给nums中除了最大值之外的其他数字
            int afterAvgLeftNum = this.leftSum - (avgLeft * (this.cnt-maxNumCount));
            if(avgLeft == 0){
                Arrays.sort(nums); //把最后的剩余和加给最小值
                nums[0] += this.leftSum;
                break;
            }
            int tempSum = afterAvgLeftNum;
            for (int i = 0; i < this.cnt; i++) {
                if (nums[i] < this.maxNum) {
                    int temp = nums[i] + avgLeft;
                    if (temp >= this.maxNum) {  //如果 (minNum + 随机生成数) + 剩余的平均值 > 最大值 178 + 41 > 180
                        nums[i] = this.maxNum;  //nums[i] = 180
                        leftNums[i] = temp - nums[i];  //178+41-180 = 39
                        tempSum += leftNums[i];
                        maxNumCount++;
                    } else {
                        nums[i] = temp;
                    }
                }
                finalSum += nums[i];
            }
            this.leftSum = tempSum;
        }
        return nums;
    }

    public int[] execute(){
        try {
            generate();
        } catch (IntegerException ex) {
            Logger.getLogger(RandomTest.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            return this.nums;
        }
    }
    private void checkMinAndMax() throws IntegerException {
        for (int i = 0; i < this.cnt; i++) {
            nums[i] = this.minNum;
        }
        if(this.maxNum * this.cnt < this.sum || this.minNum * this.cnt > this.sum)
            throw new IntegerException("参数非法");
        if (this.maxNum * this.cnt == this.sum) {
            for (int i = 0; i < this.cnt; i++) {
                nums[i] = this.maxNum;
            }
            this.isChecked = true;
        } 
        if (this.minNum * this.cnt == this.sum) {
            for (int i = 0; i < this.cnt; i++) {
                nums[i] = this.minNum;
            }
            this.isChecked = true;
        }
    }

    private int generateInt(int seed) throws IntegerException {
        if (seed < 0) {
            throw new IntegerException("Seed less than zero");
        }
        return new Random().nextInt(seed);
    }

    private class IntegerException extends Exception {

        public IntegerException(String msg) {
            super(msg);
        }
    }

    public static void main(String[] args) {
  
            RandomTest test = new RandomTest(100,400,6,500);
            int []nums = test.execute();
            int sum = 0;
            System.out.println(Arrays.toString(nums));
            for(int i = 0;i < nums.length;i++)
                  sum += nums[i];
            System.out.println("Sum="+sum);
        
    }
}
这是我的代码,
测试了下,RandomTest test = new RandomTest(100,400,6,1100); 生成了很多小于100的数 你修正下代码[/quote]
 
for (int i = 0; i < this.cnt; i++) {
            int seed1 = this.leftSum > seed ? seed:this.leftSum;
            int number = generateInt(seed1);
            nums[i] += number;
            this.leftSum -= number;
        }
请老兄再测试,谢谢
飏飏一蝶 2015-07-08
  • 打赏
  • 举报
回复
引用 25 楼 owen00sun 的回复:

public class RandomTest {

    /*idea: example{100,200,6,1080}
    1. nums = {100,100,100,100,100,100}
    * 2.generate 6 random number,nums={178,110,120,132,160,123},leftSum = 1080-823=257,avgLeft = 257/6 =42
    * 3 nums[0]+ avgLeft :if 178 + 42 > 200,then nums[0] = 200 leftNums[0] = (178+42-200)=20  maxNumCount+1
    * if 110 + 42 < 200 nums[1] = 152 leftNums[1] = 0 finalSum += nums[i]
    * 4.nums = {200,152,162,174,200,165} ,maxNumCount = 2
    * 5.if avgLeft ==0 means no avgLeftSum is small enough, add it to the min value in nums,exit loop;else loop until finalSum == sum
    */
    private int minNum, maxNum, cnt, sum, leftSum;
    private int[] nums;
    private int[] leftNums;
    private boolean isChecked = false;

    public RandomTest(int minNum, int maxNum, int cnt, int sum) {
        this.maxNum = maxNum;
        this.minNum = minNum;
        this.cnt = cnt;
        this.sum = sum;
        nums = new int[cnt];
        leftNums = new int[cnt];
    }

    private int[] generate() throws IntegerException {
        checkMinAndMax();
        if (this.isChecked) {
            return nums;
        }
        int seed = this.maxNum - this.minNum;  //生成随机数种子
        this.leftSum = this.sum - (this.cnt * this.minNum); //获取剩余的和
        for (int i = 0; i < this.cnt; i++) {
            int number = generateInt(seed);
            nums[i] += number;
            this.leftSum -= number;
        }
        int finalSum = 0;
        int maxNumCount = 0;  //统计nums中有多少个最大值
         while (finalSum != this.sum) {
            finalSum = 0;
            if(this.cnt-maxNumCount == 0){
                break;
            }
            int avgLeft = (int) Math.floor(this.leftSum / (this.cnt-maxNumCount)); //分配给nums中除了最大值之外的其他数字
            int afterAvgLeftNum = this.leftSum - (avgLeft * (this.cnt-maxNumCount));
            if(avgLeft == 0){
                Arrays.sort(nums); //把最后的剩余和加给最小值
                nums[0] += this.leftSum;
                break;
            }
            int tempSum = afterAvgLeftNum;
            for (int i = 0; i < this.cnt; i++) {
                if (nums[i] < this.maxNum) {
                    int temp = nums[i] + avgLeft;
                    if (temp >= this.maxNum) {  //如果 (minNum + 随机生成数) + 剩余的平均值 > 最大值 178 + 41 > 180
                        nums[i] = this.maxNum;  //nums[i] = 180
                        leftNums[i] = temp - nums[i];  //178+41-180 = 39
                        tempSum += leftNums[i];
                        maxNumCount++;
                    } else {
                        nums[i] = temp;
                    }
                }
                finalSum += nums[i];
            }
            this.leftSum = tempSum;
        }
        return nums;
    }

    public int[] execute(){
        try {
            generate();
        } catch (IntegerException ex) {
            Logger.getLogger(RandomTest.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            return this.nums;
        }
    }
    private void checkMinAndMax() throws IntegerException {
        for (int i = 0; i < this.cnt; i++) {
            nums[i] = this.minNum;
        }
        if(this.maxNum * this.cnt < this.sum || this.minNum * this.cnt > this.sum)
            throw new IntegerException("参数非法");
        if (this.maxNum * this.cnt == this.sum) {
            for (int i = 0; i < this.cnt; i++) {
                nums[i] = this.maxNum;
            }
            this.isChecked = true;
        } 
        if (this.minNum * this.cnt == this.sum) {
            for (int i = 0; i < this.cnt; i++) {
                nums[i] = this.minNum;
            }
            this.isChecked = true;
        }
    }

    private int generateInt(int seed) throws IntegerException {
        if (seed < 0) {
            throw new IntegerException("Seed less than zero");
        }
        return new Random().nextInt(seed);
    }

    private class IntegerException extends Exception {

        public IntegerException(String msg) {
            super(msg);
        }
    }

    public static void main(String[] args) {
  
            RandomTest test = new RandomTest(100,400,6,500);
            int []nums = test.execute();
            int sum = 0;
            System.out.println(Arrays.toString(nums));
            for(int i = 0;i < nums.length;i++)
                  sum += nums[i];
            System.out.println("Sum="+sum);
        
    }
}
这是我的代码,
测试了下,RandomTest test = new RandomTest(100,400,6,1100); 生成了很多小于100的数 你修正下代码
SaintTinyBoy 2015-07-08
  • 打赏
  • 举报
回复

public class RandomTest {

    /*idea: example{100,200,6,1080}
    1. nums = {100,100,100,100,100,100}
    * 2.generate 6 random number,nums={178,110,120,132,160,123},leftSum = 1080-823=257,avgLeft = 257/6 =42
    * 3 nums[0]+ avgLeft :if 178 + 42 > 200,then nums[0] = 200 leftNums[0] = (178+42-200)=20  maxNumCount+1
    * if 110 + 42 < 200 nums[1] = 152 leftNums[1] = 0 finalSum += nums[i]
    * 4.nums = {200,152,162,174,200,165} ,maxNumCount = 2
    * 5.if avgLeft ==0 means no avgLeftSum is small enough, add it to the min value in nums,exit loop;else loop until finalSum == sum
    */
    private int minNum, maxNum, cnt, sum, leftSum;
    private int[] nums;
    private int[] leftNums;
    private boolean isChecked = false;

    public RandomTest(int minNum, int maxNum, int cnt, int sum) {
        this.maxNum = maxNum;
        this.minNum = minNum;
        this.cnt = cnt;
        this.sum = sum;
        nums = new int[cnt];
        leftNums = new int[cnt];
    }

    private int[] generate() throws IntegerException {
        checkMinAndMax();
        if (this.isChecked) {
            return nums;
        }
        int seed = this.maxNum - this.minNum;  //生成随机数种子
        this.leftSum = this.sum - (this.cnt * this.minNum); //获取剩余的和
        for (int i = 0; i < this.cnt; i++) {
            int number = generateInt(seed);
            nums[i] += number;
            this.leftSum -= number;
        }
        int finalSum = 0;
        int maxNumCount = 0;  //统计nums中有多少个最大值
         while (finalSum != this.sum) {
            finalSum = 0;
            if(this.cnt-maxNumCount == 0){
                break;
            }
            int avgLeft = (int) Math.floor(this.leftSum / (this.cnt-maxNumCount)); //分配给nums中除了最大值之外的其他数字
            int afterAvgLeftNum = this.leftSum - (avgLeft * (this.cnt-maxNumCount));
            if(avgLeft == 0){
                Arrays.sort(nums); //把最后的剩余和加给最小值
                nums[0] += this.leftSum;
                break;
            }
            int tempSum = afterAvgLeftNum;
            for (int i = 0; i < this.cnt; i++) {
                if (nums[i] < this.maxNum) {
                    int temp = nums[i] + avgLeft;
                    if (temp >= this.maxNum) {  //如果 (minNum + 随机生成数) + 剩余的平均值 > 最大值 178 + 41 > 180
                        nums[i] = this.maxNum;  //nums[i] = 180
                        leftNums[i] = temp - nums[i];  //178+41-180 = 39
                        tempSum += leftNums[i];
                        maxNumCount++;
                    } else {
                        nums[i] = temp;
                    }
                }
                finalSum += nums[i];
            }
            this.leftSum = tempSum;
        }
        return nums;
    }

    public int[] execute(){
        try {
            generate();
        } catch (IntegerException ex) {
            Logger.getLogger(RandomTest.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            return this.nums;
        }
    }
    private void checkMinAndMax() throws IntegerException {
        for (int i = 0; i < this.cnt; i++) {
            nums[i] = this.minNum;
        }
        if(this.maxNum * this.cnt < this.sum || this.minNum * this.cnt > this.sum)
            throw new IntegerException("参数非法");
        if (this.maxNum * this.cnt == this.sum) {
            for (int i = 0; i < this.cnt; i++) {
                nums[i] = this.maxNum;
            }
            this.isChecked = true;
        } 
        if (this.minNum * this.cnt == this.sum) {
            for (int i = 0; i < this.cnt; i++) {
                nums[i] = this.minNum;
            }
            this.isChecked = true;
        }
    }

    private int generateInt(int seed) throws IntegerException {
        if (seed < 0) {
            throw new IntegerException("Seed less than zero");
        }
        return new Random().nextInt(seed);
    }

    private class IntegerException extends Exception {

        public IntegerException(String msg) {
            super(msg);
        }
    }

    public static void main(String[] args) {
  
            RandomTest test = new RandomTest(100,400,6,500);
            int []nums = test.execute();
            int sum = 0;
            System.out.println(Arrays.toString(nums));
            for(int i = 0;i < nums.length;i++)
                  sum += nums[i];
            System.out.println("Sum="+sum);
        
    }
}
这是我的代码,
飏飏一蝶 2015-07-07
  • 打赏
  • 举报
回复
不可能穷举所有情况。也没必要。手机回复不能引用。
Inhibitory 2015-07-07
  • 打赏
  • 举报
回复
还可以先减 100 * 6,用剩下的 400 来生成随机数,最后每个元素都加上100
public class Main {
    public static List<Integer> generateRandomRestrictNumbers(final int count,
                                                              final int min,
                                                              final int max,
                                                              final int target) {
        // 做参数校验,不符合就退出

        List<Integer> numbers = null;
        Random random = new Random();

        int sum = target - min * count;

        while (true) {
            int subSum = 0;
            numbers = new ArrayList<Integer>();

            // 生成 count-1 个 [min, max] 之间的随机数
            for (int i = 0; i < count - 1; ++i) {
                numbers.add(1 + random.nextInt(max - min));
                subSum += numbers.get(i);
            }

            // 计算第 count 个随机数,因为前 count-1 个数是随机的,所以第 count 个也是随机的
            if (subSum < sum) {
                numbers.add(sum - subSum);
                break;
            }
        }

        for (int i = 0; i < numbers.size(); ++i) {
            numbers.set(i, numbers.get(i) + min);
        }

        return numbers;
    }

    public static void main(String[] args) {
        List<Integer> numbers = generateRandomRestrictNumbers(6, 100, 300, 1000);
        System.out.println(numbers);
    }
}
老李家的小二 2015-07-07
  • 打赏
  • 举报
回复
有可能前n-m个数的加和已经大于设定值了。 我的思路是,能不能按照取数范围先计算出满足加和和个数等于设定值的所有数组列表 再随机取列表中的某条得到结果。
Inhibitory 2015-07-07
  • 打赏
  • 举报
回复
还需要校验第 6 个数是否也在 100-300 之间
Inhibitory 2015-07-07
  • 打赏
  • 举报
回复
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Main {
    public static List<Integer> generateRandomNumbers(int min, int max, int maxSum, int count) {
        // 做参数校验,不符合就退出

        List<Integer> numbers = null;
        Random random = new Random();

        while (true) {
            int sum = 0;
            numbers = new ArrayList<Integer>();

            // 生成 count-1 个 [min, max] 之间的随机数
            for (int i = 0; i < count - 1; ++i) {
                numbers.add(min + 1 + random.nextInt(max - min));
                sum += numbers.get(i);
            }

            // 计算第 count 个随机数,因为前 count-1 个数是随机的,所以第 count 个也是随机的
            if (sum < maxSum) {
                numbers.add(maxSum - sum);
                break;
            }
        }

        return numbers;
    }

    public static void main(String[] args) {
        List<Integer> numbers = generateRandomNumbers(100, 300, 1000, 6);
        System.out.println(numbers);
    }
}
Inhibitory 2015-07-07
  • 打赏
  • 举报
回复
先随机生成 5 个数,其和小于 1000,第 6 个数为 1000 减去这 5 个数的和。
飏飏一蝶 2015-07-07
  • 打赏
  • 举报
回复
想到一种解决方案:n个a1-a2随机数和为s,,假设有解,先给数组中每个项赋值a1,保证最小值,然后把剩下的s-a1*n随机往每一个项里放置,每次往随机的一项+1,如果该项值已满a2,则不再参与随机+1,这样能保证在s-a1*n次放置后生成任意满足条件的随机数组,包括极端情况。代码不想写了。
飏飏一蝶 2015-07-07
  • 打赏
  • 举报
回复
继续改进粒度生成方式 把区间为的随机数限制在区间内

 //粗粒度的增加
    int addInt = new Random().nextInt(left) + 1;
改为

    int addInt1 = new Random().nextInt(left);
    int addInt = addInt1 % (maxR - minR) + 1;
飏飏一蝶 2015-07-07
  • 打赏
  • 举报
回复
条件太苛刻的,本来就不适合暴力随机了,大部分正常情况几次随机可以满足条件,但极端情况又要是随机数(暴力型)又要随机数满足苛刻条件,那么就不适合考虑暴力随机了,6-290-300-1800我测试有时要几十万次才能随机成功,更何况100-300这么大的空间,随机重复概率还非常高。如果真是随机,不应该考虑极端情况,或者极端情况应该换一种考虑方式,用排列组合。
飏飏一蝶 2015-07-07
  • 打赏
  • 举报
回复
刚刚那个算法粒度太细,导致结果太平均了,看着很不爽 然后改进了算法,增加粒度 发现需要的次数更少 结果却更随机了 只要几十次就OK了 算是没有遗憾了

    public void fufil( ){
    	for (int i = 0; i < nums.length; i++) {
			nums[i] += minR;
		}
    	
    	int left = sum - numG * minR;
    	while (left > 0) {
			times++;
			int random = new Random().nextInt(numG);
    		//粗粒度的增加
			int addInt = new Random().nextInt(left) + 1;
    		if( left < addInt){
    			continue;
    		}
			if(nums[random] >= maxR || nums[random] + addInt > maxR  ){
				continue;
			}
			
			nums[random] += addInt;
			left -= addInt;
		}
    	
    	System.out.println(Arrays.toString(nums));
    }
飏飏一蝶 2015-07-07
  • 打赏
  • 举报
回复
引用 13 楼 qq118194716 的回复:
想到一种解决方案:n个a1-a2随机数和为s,,假设有解,先给数组中每个项赋值a1,保证最小值,然后把剩下的s-a1*n随机往每一个项里放置,每次往随机的一项+1,如果该项值已满a2,则不再参与随机+1,这样能保证在s-a1*n次放置后生成任意满足条件的随机数组,包括极端情况。代码不想写了。
根据我自己的这个思路,可以完美解决这个问题 运行次数也可以限制在几百次到一千多次 和值越少需要的次数越少 由于是随机数,完全靠随机生成不靠谱,重复率高而且可靠性差 所以考虑用随机填充的方法

import java.io.IOException;
import java.util.Arrays;
import java.util.Random;

public class RandomSumTest2 {
    
	/*
	 * numG 随机个数
	 * minR 随机范围下限
	 * maxR 随机范围上限
	 * sum 随机数组和
	 * nums 随机数组
	 * isFind 运算时间外没找到随机数认为无解
	 */
    private int numG;
    private int minR;
    private int maxR;
    private int sum;
    private int[] nums;
    private long times = 0;
    
    class ErrorParamsException extends IOException{
    	
		private static final long serialVersionUID = 1L;

		public ErrorParamsException(String msg) {
    		super(msg);			
		}
    	
    }
    
    private void initl(int numG,int minR,int maxR,int sum) throws ErrorParamsException{
    	this.numG = numG;
    	this.minR = minR;
    	this.maxR = maxR;
    	this.sum = sum;
    	nums = new int[numG];
    	Arrays.fill(nums, 0);
    	if(sum < numG*minR || sum > numG*maxR || minR > maxR){
    		throw new ErrorParamsException("此题无解");
    	}
    }
	
    public void setParams(int numG,int minR,int maxR,int sum) throws ErrorParamsException{
    	initl(numG, minR, maxR, sum);
    }
    
    public RandomSumTest2(int numG,int minR,int maxR,int sum) throws ErrorParamsException{
    	initl(numG, minR, maxR, sum);
    }
    
 
    public void fufil( ){
    	for (int i = 0; i < nums.length; i++) {
			nums[i] += minR;
		}
    	
    	int left = sum - numG * minR;
    	while (left > 0) {
			times++;
    		int random = new Random().nextInt(numG);
			if(nums[random] >= maxR){
				continue;
			}
			nums[random] ++;
			left --;
		}
    	
    	System.out.println(Arrays.toString(nums));
    }

      public long getTimes(){
    	  return times;
      }
		
	public static void main(String[] args) {
		try {
			//普通情况测试
			RandomSumTest2 randomSumTest2 =  new RandomSumTest2(6, 100, 300, 1100);
			randomSumTest2.fufil( );
			System.out.println("运行次数 :" + randomSumTest2.getTimes());
			//极端情况测试
			RandomSumTest2 randomSumTest3 =  new RandomSumTest2(6, 100, 300, 1799);
			randomSumTest3.fufil( );
			System.out.println("运行次数 :" + randomSumTest3.getTimes());
		} catch (ErrorParamsException e) {
			e.printStackTrace();
		}
	}

}

xxjr236 2015-07-07
  • 打赏
  • 举报
回复
public static void result(int a ,int min , int max, int sum){ Random random=new Random(); int temSum=sum - min * 6; int all=0; for( int i = 0; i<a-1;i++){ int Result=random.nextInt(temSum>max - min ? max - min:temSum); temSum =temSum-Result; System.out.println(Result+min); all=all+Result+min; } System.out.println(temSum+min); System.out.println(all+temSum+min); } public static void main(String[] args) { result(6,100,300,1000); } 根据上面的帖子的想法来的,开始以为很简单,直接看回复了,,,然后受影响了
vswen5 2015-07-07
  • 打赏
  • 举报
回复
写N条6个数组成1000的数据字典 然后在随机抓一个 哈哈~
SaintTinyBoy 2015-07-06
  • 打赏
  • 举报
回复
引用 8 楼 qq_24472595 的回复:
import java.util.Random;

public class hehe
{
int  s =0;
int  n = 0;
Random r = new Random();
   public static void main(String[] argvs)
   {
//开始
	   new hehe().show();
   }
   public void show()
   {
	   int a = 0;
	   for(int i = 0;i<6;i++)
	   {
		   n++;
//getNumber获取下一个数
		   a = getNumber();
		   System.out.println(a);
	   }
   }
   public int getNumber()
   {
	 int t = r.nextInt()%300;
	 while(s<=1000){
	//判断这个数的范围是否在100-300内
	 while( t<100||t>300 )
	  {
		  t = r.nextInt()%300;
		 
	  }
	 //尝试算s+t,看看结果是否满足要求,满足则跳出循环,不满足则继续求t,下一个循环
	  if( ok(s +t))
	  {
		  s = s +t;
		  System.out.println("yes S="+s);
		  break;
		  }
		else{
			
			 	  t = r.nextInt()%300;
			continue;
			}
		}
		return t;
   }
   public boolean ok(int s)
   {
//n 是代表当前在求第几个数
//s 是求和
	   switch(n)
	   {
		   case 1: 
		    if( s<500)
			 {return true;}
		   break;
		   case 2: 
		    if( s<600)
			 {return true;}
		   break;
		   case 3: 
		    if( s<700)
			 {return true;}
		   break;
		   case 4: 
		    if(s>400&&s<800)
			 {return true;}
		   break;
		   case 5: 
		    if( s>700&&s<900)
			 {return true;}
		   break;
		   case 6: 
		     if( s==1000)
			 {return true;}
		   break;
		   default:;
		   
	   }
	   return false;
   }
}
6这个数字是由用户输入的参数,可能输入100,难道写100个case吗
SaintTinyBoy 2015-07-06
  • 打赏
  • 举报
回复
你们输入 6 100 300 1799试试,暴力枚举
Gyanxie 2015-07-06
  • 打赏
  • 举报
回复
其中6 100-300 1000这些参数是用户设定的 不妨设6为 数n ; 100 为 数a; 300为数b; 1000为 T, 当前的和为S,还是一样的思路,既然是觉得case麻烦,那就将case归纳为一个关于n的表达式。先将上面的代码给重构简化。 先说 s 的范围, 当n=6时,有T=S, n = k 时( k=1,2,3...;k<6) 有 s<T-a*(n-k),即可,由于,程序前面保证了每个数都在(a,b)范围,所以,s的最小值肯定满足要求,所以只要保证s的最大值小于某个上限,从而保证剩下的随机数能够合理生成。.


import java.util.Random;

public class hehe
{
	int		s	= 0;
	int		n	= 0;
	Random	r	= new Random();

	public static void main(String[] argvs)
	{
		new hehe().show();
	}

	public void show()
	{
		int a = 0;
		for (int i = 0; i < 6; i++)
		{
			n++;
			a = getNumber();
			System.out.println(a);
		}
	}

	public int getNumber()
	{
		int t = r.nextInt() % 300;
		while (s <= 1000)
		{

			while (t < 100 || t > 300)
			{
				t = r.nextInt() % 300;

			}

			if (ok(s + t))
			{
				s = s + t;
				System.out.println("yes S=" + s);
				break;
			}else
			{

				t = r.nextInt() % 300;
				continue;
			}
		}
		return t;
	}

	public boolean ok(int s)
	{
		if (n == 6)
		{
			if (s == 1000) return true;
			return false;
		}

		if (s < (1000 - (6 - n) * 100)) return true;

		return false;
	}
}

再拓展到自定义的情况。

import java.util.Random;

public class hehe
{
	//一共有n 个数
	int		n	= 0;
	//n的值的最小值
	int     a   = 0;
	//n的值的最大值
	int     b   = 0;
	//n的值的最小值
	int		s	= 0;
	//当前求第k个数
	int     k   = 0;
	//和为T
	int     T = 0;
	
	Random	r	= new Random();

	public static void main(String[] argvs)
	{
		//输入  n, a,b,T的函数 自己写吧
		//创建对象
		hehe example = new hehe();
		//设置n,a,b,T的值
		example.n = 6;
		example.a = 100;
		example.b = 300;
		example.T = 1000;
		example.show();
	}

	public void show()
	{
		int result = 0;
		for (int i = 0; i < n; i++)
		{
			k++;
			result = getNumber();
			System.out.println(result);
		}
	}

	public int getNumber()
	{
		//
		int t =-1;
		while (s <= T)
		{

			//生成数t,这里优化一下,把将生成的数在0到(b-a)直接,然后再加上a的值
			while (t < 0 || t > (b-a))
			{
				t = r.nextInt() % (b-a);
			}
            //此时生成的t>=0且小于(b-a)
			//然后算出t+a;
			t = t+a;
			if (ok(s + t))
			{
				s = s + t;
				System.out.println("yes S=" + s);
				break;
			}else
			{

				t = r.nextInt() % (b-a);
				continue;
			}
		}
		return t;
	}

	public boolean ok(int s)
	{
		if (k == n)
		{
			if (s == T) return true;
			return false;
		}

		if (s < (T - (n - k) * a)) return true;

		return false;
	}
}

加载更多回复(8)

50,599

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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