# 随机数求和

SaintTinyBoy 2015-07-04 04:14:37

...全文
742 28 打赏 收藏 转发到动态 举报

28 条回复

• 打赏
• 举报

``````
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
• 打赏
• 举报

[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);

}
}
``````

``````
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;
}``````

• 打赏
• 举报

``````
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);

}
}
``````

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);

}
}
``````

• 打赏
• 举报

Inhibitory 2015-07-07
• 打赏
• 举报

``````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);
}
}
``````

• 打赏
• 举报

Inhibitory 2015-07-07
• 打赏
• 举报

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
• 打赏
• 举报

• 打赏
• 举报

• 打赏
• 举报

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

``````
int addInt1 = new Random().nextInt(left);
int addInt = addInt1 % (maxR - minR) + 1;
``````

• 打赏
• 举报

• 打赏
• 举报

``````
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));
}
``````

• 打赏
• 举报

``````
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
• 打赏
• 举报

SaintTinyBoy 2015-07-06
• 打赏
• 举报

``````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
• 打赏
• 举报

Gyanxie 2015-07-06
• 打赏
• 举报

``````

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;
}
}

``````

50,599

javaspring bootspring cloud 技术论坛（原bbs）

• 近7日
• 近30日
• 至今