如何才能跑的更快! (300分)

  • 主题发起人 主题发起人 only you
  • 开始时间 开始时间
O

only you

Unregistered / Unconfirmed
GUEST, unregistred user!
题目:一个多位数,末位是3,将末位移到首位,则新数字是原数字的2倍
要求:用一个[red]快速[/red]优良的算法计算出来这个数是多少
我的算法很简单(java),请教各位怎样才能更快些,请写出你的思路和代码!语言不限,
关键请说明思路(声明:本文无任何不良目的,请网友放心,如不放心请不必发言)
public class guessme
{
public static void main(String args[])
{
for (long i=100L;i<=1000000000000000000L ;i=i+1000000L)
{
new SimpleThread(i,i+1000000L).start();
}
System.out.println("所有线程已经全部运行完毕!");
}
}
class SimpleThread extends Thread
{
private long start;
private long end;
private long Count;
private static long Counter=0;
public SimpleThread(long astart,long aend)
{
super();
Count=++Counter;
start=astart;
end=aend;
}
public void run()
{
long j=0L;
String temp;
String NewStr;
for (long i=start;i<=end;
i++ )
{
temp=Long.toString(i);
NewStr=temp.charAt(temp.length()-1)+temp.substring(1,temp.length()-1);
long k=Long.parseLong(NewStr);
if (i<<1==k)
{
j=k;
}
}
System.out.println("第"+Count+"个线程已经运行完毕!结果是:"+j);
}
};
 
因为新数据3xx..xx = 2 * xx..xx3
所以新数据的末位一定是 6
所以这个多位数的形式应该为 xx..xx63
因为两个数的位数相同,新数据的首位为3,
鼓这个多位数的首位应该是1,
所以这个多位数的形式应该为 1xx..xx63
故最重要的是求出xx..xx就可以了!
strtoint('3'+'1'+inttostr(i)+'6')=2*strtoint('1'+inttostr(i)+'6'+'3')
通过以上方程还可以观察出这个多位数的第二位应该是>=5,当取6时2*6=12,个位2>1,不合,
鼓这个多位数的第二位应该是5,
所以这个多位数的形式应该为 15xx..xx63
故最重要的是求出xx..xx就可以了!
strtoint('3'+'1'+'5'+inttostr(i)+'6')=2*strtoint('1'+'5'+inttostr(i)+'6'+'3')
类似推法:
最后
strtoint('3'+'1'+'5'+'7'+'8'+'9'+inttostr(i)+'6')=2*strtoint('1'+'5'+'7'+'8'+'9'+inttostr(i)+'6'+'3')
求出i即可!
我的理解是这样的,不知道对吗?
 
本人比较菜,但看看也想说说!
1.这个数肯定在123。143,1003,1023。。。这样
所以能不能这样考虑:
1。设置封顶职
2。以123做开始,判断概数是否符合:
3。如不符合则取下一数,下一数这样去。
将倒数第二位加二,判断该树是否超过143 或1443(举百位的例子)
如果该数已超过,那根据数的长度。得到数所在的为,比如143 为100 就得到1003
这个数,在接着循环下去
4。有个问题是如果将字符串直接转换成整型的话是否会不如对数字进行取摸,
整除取新数那么快
 
写完后看了楼上的觉得要改改
1.这个数肯定在1063,1163。。。这样。但不会是1503
所以能不能这样考虑:
1。设置封顶职
2。以1063做开始,判断概数是否符合:
3。如不符合则取下一数,下一数这样去。
将倒数第三位加二,判断该树是否超过1463 (举位的例子)
如果该数已超过,那根据数的长度。得到数所在的为,比如1463 为1000 就得到10063
这个数,在接着循环下去
4。有个问题是如果将字符串直接转换成整型的话是否会不如对数字进行取摸,
整除取新数那么快
 
这样怎么样,
设这个数为x*10+3,
移动后的数3*(10的m次方)+x
然后得到等式
3*(10的m次方)+x=2*(x*10+3)
3*(10的m次方)=19*x+6
得到
(3*(10的m次方)-6)/19=x
x为整数,m为整数
设定m的值就可以得到x了


 
是不是可以得分了?
 
大家还是只提出了算法,其实这道题只要逐步推理是可以得到答案的!
现在的问题是要用程序实现他,并且运算速度在可以接收的范围内,
象我的野蛮普遍算法运行了整整19个小时都没得出结果,我的
机子是ALhlon 900,
 
好,我试试!
 
157894736842105263
*2=
315789473684210526
 
其实很容易
我说思路,写程序也很简单
末尾3 该数为?3 得到 (实际上是?30*2=?60)
前一数6 ?63(?63*2=?26)
前一数2 ?263(类推)
前一数5 ?5263
前一数0 ?05263
前一数1 ?105263(监测到一,需要进行验证,不符合)
前一数2 ?2105263
前一数4 ?42105263
前一数8 ?842105263
前一数6 ?6842105263
前一数3 ?36842105263
前一数7 ?736842105263
前一数4 ?4736842105263
前一数9 ?94736842105263
前一数8 ?894736842105263
前一数7 ?7894736842105263
前一数5 ?57894736842105263
前一数1 ?157894736842105263(首位为1,需要验证,符合)
是不是很容易呢?编程序也很简单的:)
 
>>陈晨
你的算法是正确的,但遗憾的是计算机不能有效的计算出来,不信你试试!
原因应该是计算机在进行浮点算法时是不精确的!所以得出的数也不准.
依照你的算法如下
import java.math.*;
class New
{
public static void main(String[] args)
{
double x;
for (double m=0D;m<=30D;m++)
{
x=3*(Math.pow(10,m)-6)/19;
System.out.println("x="+x);
}
}
}
结果是
---------- java ----------
x=-0.7894736842105263
x=0.631578947368421
x=14.842105263157896
x=156.94736842105263
x=1578.0
x=15788.526315789473
x=157893.7894736842
x=1578946.4210526317
x=1.5789472736842105E7
x=1.5789473589473686E8
x=1.5789473674736843E9
x=1.5789473683263159E10
x=1.578947368411579E11
x=1.5789473684201052E12
x=1.5789473684209578E13
x=1.578947368421043E14
x=1.5789473684210518E15
x=1.5789473684210526E16
x=1.57894736842105248E17
x=1.57894736842105267E18
x=1.5789473684210526E19
x=1.5789473684210526E20
x=1.5789473684210526E21
x=1.5789473684210525E22
x=1.5789473684210524E23
x=1.578947368421053E24
x=1.5789473684210528E25
x=1.578947368421053E26
x=1.5789473684210528E27
x=1.5789473684210527E28
x=1.5789473684210527E29
Normal Termination
输出完成(耗费 0 秒)。
 
>>shenloqi
最好写出你的算法实现
 
设这个数去掉个位数3后所得的数为 x;
设 x 为 n 位数。
则:(x * 10 + 3) * 2 = 3 * (10 的 n 次方) + x
即:x = (3 * (10 的 n 次方) - 6) div 19
下面是算法:
procedure TForm1.Button1Click(Sender: TObject);
var
i,n:integer;
x,xxx,m:int64;
begin
for n:=1 to 18do
begin
xxx:=1;
for i:=1 to ndo
xxx:=xxx*10;
m:=3*xxx-6;
x:=m div 19;
if m=x*19 then
ListBox1.Items.Add(inttostr(x)+'3')
end;
end;
答案只有一个:157894736842105263
 
楼上算法更优:)
我的是
function GetIt:Extended;
type
TNumBit = 0..9;
var
a:array of TNumBit;
i, j:Integer;
itmp,itmp2:Extended;
begin
SetLength(a, 2);
a[0] := 3;
a[1] := 6;
itmp := 0;
itmp2 := 0;
for i := 2 to MaxIntdo
begin
SetLength(a,i + 1);
a := (a[i - 1] * 10 + a[i - 2]) * 2 div 10 mod 10;
if a = 1 then
begin
for j := High(a)do
wnto Low(a)do
begin
itmp := itmp + a[j] * IntPower(10, j);
if j > 0 then
itmp2 := itmp2 + a[j] * IntPower(10, j - 1)
else
itmp2 := itmp2 + a[j] * IntPower(10, High(a));
end;
end;
if (itmp <> 0) and (itmp * 2 = itmp2) then
Break;
end;
Result := itmp;
end;
 
设这个数去掉个位数3后所得的数为 x;
设 x 为 n 位数。
则:(x * 10 + 3) * 2 = 3 * (10 的 n 次方) + x
即:x = (3 * (10 的 n 次方) - 6) div 19应为整数;
function GetValue(MaxValue:Integer):Int64;
//maxvalue为最大位数,返回结果值
var
N: Integer;
x,m,xxx: Int64;
begin
xxx:=1;
for N:=1 to MaxValuedo
begin
xxx:=xxx*10;
if ((3*xxx-6) mod 19)=0 then
break;
end;
result := ((3*xxx-6) div 19)*10+3;
end;
 
多人接受答案了。
 
后退
顶部