站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2SE 专题JAVA新手求解一道算法题?得解马上结贴!

JAVA新手求解一道算法题?得解马上结贴!

摘要: JAVA新手求解一道算法题?得解马上结贴!


找三个三位数(A=xxx,B=xxx,C=xxx);

X={1~9} 每个数只能出现一次,如:(A=123,B=456,C=789);

这三个三位数还要满足两个条件:

第2个数是第一个数的2倍,第3个数是第1个数的3倍(B=2A ,C=3A);

希望代码效率越高越好!!


int x,y,z;
banlance[int];
for(int i =0 ;i -#60; 10 ;i++){
x = i;
y = i*2;
z = i*3;
if(x-#60;-#62;y){
if(x-#60;-#62;z){
if(y-#60;-#62;z){
banlance[i] = -#34;-#34;+x+y+z;
}
}
}
if(banlance[3]-#60;-#62;null){
//continue;
brack;
}
}


这也太简单了吧


不好意思。写错了。balance[]
为什么这么问题呢?其实如果要算的话。因为要算的是倍数关系。可以。



不知道。很久没写程序


接分


再说下题目意思是:

A,B,C 三个都是三位数。并不是ABC组成1个三位数
第2个数是第1个数的2倍,第3个数是第1个数的3倍;(B=2*A ,C=3*A);

三个三位数(A=xxx,B=xxx,C=xxx);

X={1~9} (1~9)每个数只能出现一次 例如 A如过是一百三十二(123),B就只能是四到九了(四百五十六 456) C就只能是(7~9)





写错了:
X={1~9} (1~9)每个数只能出现一次 例如 A如过果一百三十二(132),B就只能是四到九了(四百五十六 456) C就只能是(7~9)


嗯,这样说还有才有点难度


用hashcode


int length = 3;
java.util.Random rand = new Random();

String base = -#34;123456789-#34;;
int size = base.length();
StringBuffer str = new StringBuffer();
for (int i = 0; i -#60; length; i++) {
int start = rand.nextInt(size);
String A = base.substring(start, start + 1);


UP...........


我觉得没有三个三位数可以满足你的要求,只有一个.123
程序你自己写吧思路清晰就可以 java中不等于用!=


哪位高手能在说详细点么?



第一个3位数:192 第二个3位数:384 第三个3位数:576
第一个3位数:219 第二个3位数:438 第三个3位数:657
第一个3位数:267 第二个3位数:534 第三个3位数:801
第一个3位数:273 第二个3位数:546 第三个3位数:819
第一个3位数:327 第二个3位数:654 第三个3位数:981
代码写得太lj了。。


楼上大概用的也是穷举吧?


A从123 ~ 345穷举


第一个3位数:192 第二个3位数:384 第三个3位数:576
第一个3位数:219 第二个3位数:438 第三个3位数:657
第一个3位数:267 第二个3位数:534 第三个3位数:801 -#60;-----看清楚,这个不算,有0没9
第一个3位数:273 第二个3位数:546 第三个3位数:819
第一个3位数:327 第二个3位数:654 第三个3位数:981

还有,按楼主所说,此题无解

再说下题目意思是:

A,B,C 三个都是三位数。并不是ABC组成1个三位数
第2个数是第1个数的2倍,第3个数是第1个数的3倍;(B=2*A ,C=3*A);

三个三位数(A=xxx,B=xxx,C=xxx);

X={1~9} (1~9)每个数只能出现一次 例如 A如过是一百三十二(123),B就只能是四到九了(四百五十六 456) C就只能是(7~9) -#60;-----C只能有7,8,9这3个数字组成,无解




呵呵,楼主题意有误,给分下一题吧


....


三个三位数(A=xxx,B=xxx,C=xxx);

X={1~9} (1~9)每个数只能出现一次 例如 A如过是一百三十二(123),B就只能是四到九了(四百五十六 456) C就只能是(7~9) -#60;-----C只能有7,8,9这3个数字组成,无解


这只是个例子呢;
A也可以是215 随便都可以 C也可以是436;
反正3个三位数,1~9个数字在他们中间必须出现一次且不能重复。


第一个3位数:192 第二个3位数:384 第三个3位数:576
第一个3位数:219 第二个3位数:438 第三个3位数:657
第一个3位数:273 第二个3位数:546 第三个3位数:819
第一个3位数:327 第二个3位数:654 第三个3位数:981

那不用程序了,楼上一位强哥已经算出来了,貌似这题一共4解


第一个3位数:327 第二个3位数:654 第三个3位数:981
第一个3位数:192 第二个3位数:384 第三个3位数:576
第一个3位数:273 第二个3位数:546 第三个3位数:819
第一个3位数:327 第二个3位数:654 第三个3位数:981
——————————————
这些都应该算吧。
但是用什么比较效率代码可以找出来呢~


从123到333穷举!才算211*70%=150个左右(其实一共126个),算你主频率1500,折合CPU运算时间不会超过0.1秒.


--------------------------------------算法写好了-------------------------------
C:/jdk5/bin-#62;java SelectNum
192 384 576
219 438 657
267 534 801
273 546 819
327 654 981

C:/jdk5/bin-#62;
--------------------------------------------------------------------------------
public class SelectNum{
public static void main(String args[]){
int a=102,b,c;
while(a-#62;=102 -#38;-#38; a-#60;=329){
b=2*a;
c=3*a;
String aStr=strInt(a);
String bStr=strInt(b);
String cStr=strInt(c);
String all=aStr+bStr+cStr;

if(noSame(aStr) -#38;-#38; noSame(bStr) -#38;-#38; noSame(cStr) -#38;-#38; noSame(all)){
System.out.print(a+-#34; -#34;);
System.out.print(b+-#34; -#34;);
System.out.print(c);
System.out.println();
}
a++;
}
}

public static String strInt(int x){
return (-#34;-#34;+x);
}

public static boolean noSame(String str){
char[] getCh=str.toCharArray();
int i;
for(i=0;i-#60;getCh.length;i++){
for(int j=i+1;j-#60;getCh.length;j++){
if(getCh[i]==getCh[j]){
return false;
}
}
}
return true;
}
}


恩,要研究
不过楼主的意思是去0,只是1到9


只要先确定a 的范围,后面的就好办了。
比较懒的一个思考法是:a-#62;=100 且 3a-#60;1000,先得一粗略范围。


所以,楼楼上的写法还是有点问题
你可能会找到

第一个3位数:267 第二个3位数:534 第三个3位数:801

不符合题意,所以建议更改下



哈哈,以偶看,懒人方法,123到329,其中一共计算126次,可以得到结果
而楼上光//while(a-#62;=102 -#38;-#38; a-#60;=329)//循环就227次了,所以是不是有点...


那就在if里面再加一条,是0的字符就pass.


错了
//while(a-#62;=102 -#38;-#38; a-#60;=329)//
是228次


有时候,穷举不见得比循环判断慢多少哦,特别是CPU的运算速度允许的情况下...
睡觉去了,明天接着聊


那就请HeartLost()兄放个代码上来观摩下嘛`
还有个各位牛人。。。
后天准时结贴``呵呵


//效率绝对OK

import java.math.*;
public class sencond
{
int[] b=new int[9];
public void getWei(int number,int i)
{
b[i]=number/100;
b[i+1]=number/10;
b[i+1]=b[i+1]%10;
b[i+2]=number%100;
b[i+2]=b[i+2]%10;

}
public void sencond()
{

}
public boolean comp()
{
int i=0,j=9,k=0;
for(k = 0;k -#60;9;k++)
{
for (i = 0; i -#60; j-1; i++)
{
if(b[i]==b[j-1])
{
return false;
}
}
j--;
}
return true;
}
public void run()
{
int a=123,b,c;
while(a-#60;=329)
{
if(a%5==0)
{
a++;
}
b=a*2;
c=a*3;
getWei(a,0);
getWei(b,3);
getWei(c,6);
if(comp())
{
System.out.println(a+-#34;/n-#34;+b+-#34;/n-#34;+c+-#34;/n-#34;);
}
a++;
}
}
public static void main(String args[])
{
sencond s=new sencond();
s.run();
}
}


刚才没看清不能有0 如果有能有零的话,a的范围当然是不从102 开始了。
再在 noSame() 的if(getCh[i]==getCh[j]) 加一条 if(getCh[i]==getCh[j] || getCh[i]==-#39;0-#39;) 就OK了。


上面我的算法绝对OK
答案是:
192 384 576
219 438 657
267 534 801
273 546 819
327 654 981
5组


现在答案中没有含0的项了。


改动一下:

public class SelectNum{
public static void main(String args[]){
int a=123,b,c;
while(a-#62;=123 -#38;-#38; a-#60;=329){ //改为a-#62;=123
b=2*a;
c=3*a;
String aStr=strInt(a);
String bStr=strInt(b);
String cStr=strInt(c);
String all=aStr+bStr+cStr;

if(noSame(bStr) -#38;-#38; noSame(cStr) -#38;-#38; noSame(all)){
System.out.print(a+-#34; -#34;);
System.out.print(b+-#34; -#34;);
System.out.print(c);
System.out.println();
}
a++;
//加个判断
while(!noSame(aStr))a++;
}
}

public static String strInt(int x){
return (-#34;-#34;+x);
}

public static boolean noSame(String str){
char[] getCh=str.toCharArray();
int i;
for(i=0;i-#60;getCh.length;i++){
for(int j=i+1;j-#60;getCh.length;j++){
if(getCh[i]==getCh[j]){
return false;
}
}
}
return true;
}
}



恩。。。
如果加点注释更好了
星期天结贴


不要每次a++都循环 先判断a是否符合条件 会比较好


while(!noSame(strInt(a))a++;//错了 改成 可以减少些计算量


还是改错了吧。。呵呵


比较数字相同的时候可以换成先折半排序再找会好点吧,不然就是2重循环了。。


提点建议:

首先:a的第一位只有三种选则,分别是1,2,3。
其次:a确定了以后,b和c也就确定了。
最后:当a的第一位为1时,a 有8!/(2!*6!)=28个数可以选则。所以a一共有84种选则。

我认为这个要比(a-#62;=123 -#38;-#38; a-#60;=329)少很多无用的情况。


我认为,现在这种算法的灵活性较好。如果 要求A B C 是四位数,或五位数的话,只需要重新确定A的范围就好了,尽管会增加一定的时间复杂度。


试了一下。四 五位数的数没有。不过,若把A的起始值改为1 就能把所有的结果都打出来了。


这样,还得在主函数的if中加一条 A B C 生成的数组长度必须相等。


用群举法,


楼主,如果你还看的话,我给你一个比较NB的答案

public class num
{
public static void main(String args[])
{
for(int i=123;i-#60;329;i++)
{
if(((i%100)/10+((2*i)%100)/10+((3*i)%100)/10)%3==0 -#38;-#38; (i/100+((2*i)%100)/10+((3*i)%100)%10)%3==0)
if(i/100+(i%100)/10+(i%100)%10+(2*i)/100+((2*i)%100)/10+((2*i)%100)%10+(3*i)/100+((3*i)%100)/10+((3*i)%100)%10==45)
System.out.println(i+-#34; -#34;+2*i+-#34; -#34;+3*i);
}
}
}

可以计算出来结果


可惜没分了


if(((i%100)/10+((2*i)%100)/10+((3*i)%100)/10)%3==0 -#38;-#38; (i/100+((2*i)%100)/10+((3*i)%100)%10)%3==0)
//判断符合结果的原始矩阵表
if(i/100+(i%100)/10+(i%100)%10+(2*i)/100+((2*i)%100)/10+((2*i)%100)%10+(3*i)/100+((3*i)%100)/10+((3*i)%100)%10==45)
//判断原始矩阵表的各数字之和等于1+2+3+...9=45?

是就输出,不是就next


up


jinxin19831117 真实强人
我在想做noSame()判断时,不必做那么多循环,如果用Set 不知是不是好一些,因为Set没有重复值。

Set set = new HashSet();
for (int i = 0; i -#60; 9; i++) {
set.add(new Integer(char[i]));
}
if (set.size() == 9) {
return true;
}

一点小思路,还不知好不好?


各位同学好。
我是老同学。
就将此处女帖献给这场小讨论吧 :)

以下的想法与上面的所有想法都不同。

这一类的问题,如果先从比较小的整数来考虑,一般来说,会比较容易找到简单些的方法。
(例如,在解决三位数的问题之前,先研究一下一位数的情况, etc.)

然后,也要先考虑一下用纸和笔计算乘法的一般步骤。

于是发现下表:
a 2a 3a
1 2 3
2 4 6
3 6 9
4 8 2
5 0(本行报废)
6 2 8
7 4 1
8 6 4
9 8 7

上表描述了最低位的规律。

于是,对于个位,需要尝试 8 次。
对于每个上述的尝试值,十位成为最低位。于是,在从 1-9 的数中筛掉用过的元素后,再利用上表对十位进行尝试 。。。

(( 编程时要考虑进位,以及沿由1到9的方向从表取数,并从未知数1向未知数3方向填数。))

我觉得这个算法已经相当浅了。
是否还有更浅的算法?


↑返回目录
前一篇: 关于xml的问题,急!!!!!!!!!!!在线等(100分)
后一篇: 虚拟机问题,,,,急