高分悬赏!!!随机数问题。

snowrain_2008 2009-04-28 08:57:59
这里有2个数组,
int x[]={1908,4218,5767,6416,8637,15614,8948,
17723,13698,9867,35085,16705,20595,50504,53688,
23548,25477,20345,18336,24645,68070,10552,10024,
17810,13219,14645,20105,13903,24035,20474,43073};

int y[]={91009,14869,15459,18354,19054,22573,33566,19850,
26725,22593,15877,34075,23895,24990,59862,48301,
11417,13657,10059,5466,18403,36273,8326,14760,
8573,5079,4144,6197,1524,2042,670};
要求目标数组rain[31][31]里面随机生成数值。并且
1。。。。。。。。。。。。。。rain数组里面第一行只有一个元素,第二行有2个元素,第三行有3个元素。以此类推
2。。。。。。。。。。。。。。随机产生的值第一行总和等于x[0],第二行总和等于x[1],第三行总和等于x[2],以此类推。
3。。。。。。。。。。。。。。同时要保证第一列的总和等于y[0],第二列总和等于y[1],第三列总和等于y[2],以此类推。
4.。。。。。。。。。。。。。。随机值要在200以上15000以下。

以上皆为要求。特此悬赏120分。。。不好意思,没权限发120分,只能发100分。
先可以简单看出rani数组有2个值是给定了的。就是rain[0][0]肯定是1908,rain[31][31]肯定是670.
...全文
288 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
hc0120 2009-05-03
  • 打赏
  • 举报
回复
神呐!
yangc_83 2009-04-30
  • 打赏
  • 举报
回复
人才啊!
jinxfei 2009-04-30
  • 打赏
  • 举报
回复
不容易,终于做出来了:


import java.util.Random;

public class SuijiShuzu {
private static int randMax = 15000, randMin = 200;
private static int arrayDimension = 31;

private static int x[]={1910,4218,5767,6416,8637,15614,8948,
17723,13698,9867,35086,16705,20596,50504,53689,
23548,25478,20346,18336,24645,68070,10552,10024,
17810,13219,14645,20105,13904,24035,20474,43073};

private static int y[]={91009,14869,15459,18354,19054,22573,33566,19850,
26725,22593,15877,34075,23895,24990,59862,48301,
11417,13657,10059,5466,18403,36273,8326,14760,
8573,5079,4144,6197,1524,2042,670};

public static void main(String[] args) {
System.out.println("sum of array x:"+sum(x)+", sum of array y:"+sum(y));
Random rand = new Random(System.currentTimeMillis());
int[][] rain = new int[arrayDimension][arrayDimension];
// 逆向思维啊
// 第一步,既然最小值是200,则,先按要求给可能有数的点都填上200再说
//满足第一点约束:rain数组里面第一行只有一个元素,第二行有2个元素,第三行有3个元素。以此类推
for (int i = 0; i < arrayDimension; i++) {
for (int j = 0; j <= i; j++) {
rain[i][j] = randMin;
}
}
// 第二步,把已经放到数组中的200,按行、列之和从x、y两个数组中减去
for (int i = 0; i < arrayDimension; i++) {
x[i] -= (i + 1) * randMin;
y[arrayDimension - i - 1] -= (i + 1) * randMin;
}

//第三步,把X数组中的每一个元素x[i],按照对应的y[j]/sum[y]的比例,平均分布到该行的各数据点,
//在分布的过程中,增加一定的随机性(正负50,可以调)
for (int i = 0; i < arrayDimension; i++) {
int currentX=x[i];
int sumY=sum(y,0,i+1);
for (int j = 0; j <= i; j++) {
long share=(long)(1L*currentX*y[j])/(long)sumY;
int nextRand=rand.nextInt(100)-50;
long preResult=rain[i][j]+share+nextRand;
if (preResult>randMin && preResult<randMax){
share+=nextRand;
}
rain[i][j] += share;
x[i]-=share;
y[j]-=share;
}
}

// 第四步,我们把X数组中剩下的值,分发到对应行的随机列上,分发到某列的同时,我们在这个列对应的y数组中,也减去1,
// 经过这一步,可以保证X数组全部为0,也就是,每行的和 符合要求。
int count=0;
for (int i = x.length-1; i >=0; i--) {
while (x[i] != 0) {
// 这里随机产生的是一个坐标值x,如果rain[i][x]<randMax,则rain[i][x]++
int nextRand = rand.nextInt(i+1);
if (rain[i][nextRand] < randMax && rain[i][nextRand]>randMin) {
if (x[i]>0){
rain[i][nextRand]++;
x[i]--;
y[nextRand]--;
}else{
rain[i][nextRand]--;
x[i]++;
y[nextRand]++;
}

}
}
}
//最后一步,由于行已经符合要求,但列可能不符合要求,
//所以我们要根据y数组中当前值(可能有负数)来做列迁移(挖高补低),一直到y数组中也全部为0
for(int i=0; i<y.length;i++){
while (y[i]>0){//如果当前的列和值小于0,则说明当前列还需要做行调整
int negIndex=findNegative(y);//首先找到一个列和值为负数的下表,就在这两列之间调整

if (negIndex<0){
System.out.println("终于完事儿了!");
break;
}else{
int adjustRowIndex=negIndex;
if (y[negIndex]+y[i]>=0){
rain[adjustRowIndex][negIndex]+=y[negIndex];
rain[adjustRowIndex][i]-=y[negIndex];
y[i]+=y[negIndex];
y[negIndex]=0;

}else{
rain[adjustRowIndex][negIndex]-=y[i];
rain[adjustRowIndex][i]+=y[i];
y[negIndex]+=y[i];
y[i]=0;
}
}
}
}
System.out.println("随机数组:");
dump(rain);
System.out.println("sum of array x:"+sum(x)+", sum of array y:"+sum(y));
}

private static int findNegative(int[] array){
for(int i=0; i<array.length;i++){
if (array[i]<0){
return i;
}
}
return -1;
}
private static void dump(int[][] array) {
for (int i = 0; i < array.length; i++) {
dump(array[i]);
}
}

private static void dump(int[] array) {
for (int j = 0; j < array.length; j++) {
System.out.print(array[j] + "\t");
}
System.out.println();
}
private static int sum(int[] array){
int sum=0;
for(int i=0; i<array.length;i++){
sum+=array[i];
}
return sum;
}
private static int sum(int[] array,int start, int end){
int sum=0;
for(int i=start;i<end;i++){
sum+=array[i];
}
return sum;
}
private static int min(int a, int b){
return a<b?a:b;
}
}


jinxfei 2009-04-29
  • 打赏
  • 举报
回复
先可以简单看出rani数组有2个值是给定了的。就是rain[0][0]肯定是1908,rain[31][31]肯定是670.

红色部分结论不对,没有规定第一行的一个数必须在0,0位置。
yesvery 2009-04-29
  • 打赏
  • 举报
回复
这是一个31元1次方程,如果有解,应该是唯一的解。用随机数来凑,效率太低。
可惜这题肯定无解,因为x[]中的各元素之和与y[]里的各元素之和 不相等(差8)
请楼主检查一下,数据错在哪里。
注:x[]中的各元素之和应该等于rain[][]中的各元素之和
y[]中的各元素之和也应该等于rain[][]中的各元素之和
yesvery 2009-04-29
  • 打赏
  • 举报
回复
再做思考后,发现我原先的想法有误。
这是一个496元1次不定方程,其解N多。
不知楼主为何不用解方程的思路,而一定要用随机数去凑。
这个问题的确很有意思,可惜太忙,无暇关顾。
这个问题对楼主真的很重要吗?
jinxfei 2009-04-29
  • 打赏
  • 举报
回复
晕,
我计算了一下x数组和y数组的和:
sum of array x:637634, sum of array y:637642

不相等,所以这个题目不可能完成。

楼主是不是抄错了数字?
snowrain_2008 2009-04-29
  • 打赏
  • 举报
回复
yesvery是牛人,说的一点没错.数据的确是错了.所以特地数据从新改了下.
x[]={1910,4218,5767,6416,8637,15614,8948,
17723,13698,9867,35086,16705,20596,50504,53689,
23548,25478,20346,18336,24645,68070,10552,10024,
17810,13219,14645,20105,13904,24035,20474,43073};

y[]={91009,14869,15459,18354,19054,22573,33566,19850,
26725,22593,15877,34075,23895,24990,59862,48301,
11417,13657,10059,5466,18403,36273,8326,14760,
8573,5079,4144,6197,1524,2042,670};
pathuang68 2009-04-28
  • 打赏
  • 举报
回复
snowrain_2008 2009-04-28
  • 打赏
  • 举报
回复
可以重复的。8楼的说的不错,最后的数值是rain[30][30]=670;
这个问题想了许久都没想出。望诸位高手给个解答。
yesvery 2009-04-28
  • 打赏
  • 举报
回复
算法思路,供楼主参考
1 创建数组rain[30][30]

2 为 rain 赋值,具体方法:
rain[0][0]=1908,其余的rain[0][x]=0
rain[1][0]=随机数,rain[1][1]=随机数,其余的rain[1][x]=0
rain[2][0]=随机数,rain[2][1]=随机数,rain[2][2]=随机数,其余的rain[2][x]=0
rain[3][0]=随机数,rain[3][1]=随机数,rain[3][2]=随机数,rain[3][3]=随机数,其余的rain[3][x]=0
依此类推,直到rain[30][x]全部赋以随机数

3 编制两个循环,分别将数组的各数据按横向以及纵向相加,与x[]以及y[]的相应元素相比较:
若有任何不相等,就退出循环,重新回到第二步,再来一遍。
若无不等,则数组 rain 中的各元素数值就是所需结果
yesvery 2009-04-28
  • 打赏
  • 举报
回复
算法思路,供楼主参考
1 创建数组rain[30][30]

2 为 rain 赋值,具体方法:
rain[0][0]=1908,其余的rain[0][x]=0
rain[1][0]=随机数,rain[1][1]=随机数,其余的rain[1][x]=0
rain[2][0]=随机数,rain[2][1]=随机数,rain[2][2]=随机数,其余的rain[2][x]=0
rain[3][0]=随机数,rain[3][1]=随机数,rain[3][2]=随机数,rain[3][3]=随机数,其余的rain[3][x]=0
依此类推,直到rain[30][x]全部赋以随机数

3 编制两个循环,分别将数组的各数据按横向以及纵向相加,与x[]以及y[]的相应元素相比较:
若有任何不相等,就退出循环,重新回到第二步,再来一遍。
若无不等,则数组 rain 中的各元素数值就是所需结果
yesvery 2009-04-28
  • 打赏
  • 举报
回复
最后的那个数 应该是rain[30][30]吧?
huangan0301 2009-04-28
  • 打赏
  • 举报
回复
顶~
yesvery 2009-04-28
  • 打赏
  • 举报
回复
感觉不是随机数的问题,而是求解线性方程的问题
jeans_zh 2009-04-28
  • 打赏
  • 举报
回复
看到数组我就晕了!
JarodYv 2009-04-28
  • 打赏
  • 举报
回复
rain中的数能否重复?
qybao 2009-04-28
  • 打赏
  • 举报
回复
这道题,因为有随机生成,所以难度比较大
首先通过回溯法求出所有解,然后再从所有解中随机取一组
这个跟以前的一道题类似,大概如下的形式,具体忘了
a1 b1 c1 ? e1
? b2 c2 d1 ?
a3 ? ? ? e3
? ? c4 ? ?
然后每一行的?有条件限制
当时用回溯法实现过,如果只求一个解,很快的,要求所有解,跑了半个多小时都没跑完
如果LZ这个显得更复杂,还是31x31(当然最终不是31x31,而是像99乘法表一样)
现在没环境,先mark一下了


znwuyan318 2009-04-28
  • 打赏
  • 举报
回复
感觉像是在做数学题哈
xuezhanliang6886 2009-04-28
  • 打赏
  • 举报
回复
顶顶顶!!
打开链接下载源码: https://pan.quark.cn/s/589796089f72 C++课程设计任务列表,涵盖以下内容:1、识别并显示10至99范围内,各位数乘积超过各位数和的数值,例如数字12不满足条件,因为1乘以2小于1加2,故不输出;而数字27满足条件,因为2乘以7大于2加7,因此需要输出该数。2、开发一个功能,用于从用户输入的任意数量实数中找出最大值与最小值:首先要求用户输入一个正整数n,代表数值的个数,随后用户可输入任意n个实数,程序需找出这n个数中的最大值和最小值并将它们展示出来。3、实现两个已排序数组的合并操作:设有数组A和B,且假设这两个数组的元素均已按照降序排列。编写程序将A和B合并成一个新的数组C,并确保C中的元素同样保持降序排列。int A[10]={123, 86,80, 49,33,15,7,0,-1,-3};int B[10]={100,64,51,50,27,19,15,12,5,2};4、设计一个函数,用于计算特定分数序列前n项的总和,该序列为1/2,1/3,1/4,1/5,1/6,1/7,...。要求在主程序中提示用户输入一个整数n,并验证输入的合法性(n需大于1方为有效),若输入合法,则调用求和函数并显示计算结果。5、编写一个程序,计算两个用户输入日期之间的天数差:用户需以year1,month1,day1和year2,month2,day2的格式输入两个日期,程序随后计算这两个日期之间的天数间隔,并将结果输出到屏幕上。要求编制具有如下原型的函数difs2Date:long GetDayDifference(int y1,int m1,int d1,int y2,int m2,int d2);并在主函数中调用此函数,将计...
代码下载地址: https://pan.quark.cn/s/ee8627e4e6d7 ABAP调试器是一种功能强大的工具,可用于在执行期间对ABAP代码进行检验。除了常规的核心功能(例如逐行运行代码以及检验变量、字段符号和引用的值)之外,它还提供了一些辅助性的特性,能够简化并压缩调试会话的时长。并非所有使用者都熟悉这些辅助特性。SAP ABAP调试器是处理和优化ABAP代码开发与维护工作的核心资源,它配备了多样的功能来协助开发人员在运行状态下进行检验和排除故障。此资源着重阐述了ABAP调试器的一些高级特性,涵盖了深入分析调用堆栈、系统级调试、更新会话调试以及提升调试效率的方法。 1. **深入分析调用堆栈**:除了常规的应用程序调试,开发人员有时需要对调用堆栈的内部层级进行深入调试,特别是在错误出现在异步执行的更新处理或系统级程序时。通过启用**系统级调试**,可以访问通常不公开的系统代码,但这也会导致调用堆栈的显著增加,因此需要审慎操作。 2. **系统级调试**:对于不含业务逻辑的系统级程序,开发人员通常无需进行调试。然而,在特定情形下,例如进行错误追踪时,可能需要进入系统代码。借助调试器的“系统调试启用/禁用”选项,可以赋予对系统程序的调试权限。 3. **更新会话调试**:在处理异步更新任务,例如持久化业务数据时,错误可能发生在更新任务内部。激活**更新会话调试**,在更新任务完成后,调试器将自动启动,展示执行路径。比如,在变更成本中心后,通过输入调试指令 "/h" 启动调试,保存后能够看到更新过程中的错误。 4. **分析调用堆栈**:在进行深入调试时,调用堆栈是至关重要的。通过分析调用堆栈,能够定位到引发问题的具体位置,如在VB_V2_NORMAL...
源码链接: https://pan.quark.cn/s/a4b39357ea24 小程序雷达 AI 驱动的小程序生态选型与风险评估工具,把微信小程序开发资源转化为可筛选、可评估、可对比的技术雷达。 线上地址 主站: Vercel: 适合谁 正在做微信小程序技术选型的产品、研发和架构团队。 需要判断 Taro、uni-app、原生小程序、组件库、云开发和 SDK 风险的团队。 需要把历史 awesome 列表转成可筛选、可对比、可验证技术雷达的维护者。 可以做什么 Radar:按推荐状态、风险等级、资源类型、分类和适用场景浏览小程序生态资源。 Quick Search:快速搜索资源并跳转常用页面。 Compare:对比 Taro、uni-app、原生小程序等核心方案。 Advisor:输入选型问题,获得推荐结论、适用/不适用条件、迁移成本、下一步和证据来源。 Doctor:粘贴小程序项目配置,识别框架依赖、过时方案和迁移风险。 Weekly:查看小程序生态周报和近期风险信号。 数据概览 当前数据集中包含 236 个小程序生态资源。 完整资源可在 Radar 页面和导出能力中查看。 核心样例 Taro ★30.6k+ - 使用 React 的方式开发小程序的框架,同时支持生成多端应用 uni-app ★36.1k+ - 使用 Vue 语法开发小程序、H5、App的统一框架 MPX ★2.1k+ - 增强型小程序框架,深度性能优化,支持跨小程序平台开发,完全兼容原生小程序组件 WePY ★21.7k+ - 支持组件化的小程序开发框架 vant-weapp ★12.3k+ - 高颜值、好用、易扩展的微信小程序 UI 库 tdesign-miniprogram ★1.3...

13,096

社区成员

发帖
与我相关
我的任务
社区描述
Java J2ME
社区管理员
  • J2ME社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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