50,348
社区成员




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);
}
}
}
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);
}
}
这是我的代码,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);
}
}
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);
}
}
//粗粒度的增加
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();
}
}
}
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;
}
}