讨论 / 应该就是个分子分母处理问题
qiezifxj 2012-08-25 01:09:00
点我顶贴 收藏 删除
PID:507 光的反射

把输入的小数转化为分数,然后化简为最简分数,在AB和CD上反射次数等于分子-1,在AD和BC上的反射次数等于分母-1。

懂反射的一般都知道通过做对称图来做反射线,个人感觉上述做法应该是对的。

关键在于无限循环小数的转化:

例如,输入0.876 Y

其实0.876876876........=876/999

化简后为:292/333

反射总次数应为:292-1 + 333-1==623

同理:0.123456789123456789123456789.............=123456789/999999999

本人感觉上述算法应该没有错误,但是写出来的代码却有四个测试点过不了。还请高手指正!

#1 naocan@2010-04-13 05:33:00
回复 删除
呃,你再试试吧
#2 许烨闻@2010-04-14 06:49:00
回复 删除
板凳~

LZ,请别这样算,如果就这么简单的话,连学过循环小数的三四年级学生都算的出来。

如果连动规都不需要,这道题目不就成了水题了吗?

#3 qiezifxj@2010-04-14 19:44:00
回复 删除
楼上的可以给证明一下错误吗?

或者给个反例也行啊!

#4 naocan@2010-04-15 06:24:00
回复 删除
板凳~

你现在别一直动规动规的好不?

那你给楼主说一下算法啊?~^_^~

#5 Jollwish@2010-04-24 04:21:00
回复 删除
回复 板凳许烨闻 的帖子

楼主是近似正解,板凳您的想法是错的。

楼主的问题在于,分数忘了约分了。。

#6 hbmhalley@2010-08-11 07:12:00
回复 删除
把它想成一张网格不久没有反射了嘛..

#include <cstdio>

#define G getchar()

int a=0, b=1, t;

char c;

inline int gcd(int a, int b) {while ( b ) {t=a; a=b; b=t%a;} return a;}

int main(void) {

if ( G=='1' ) puts("0");

else {

for (c=G; (c=G)>='0' ;b*=10) a=a*10+c-'0';

b-=G=='Y';

printf("%d\n", (a+b)/gcd(a, b)-2);

}

}

#7 ahfy_zyt@2011-08-24 08:14:00
回复 删除
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD

看了终于AC了,感谢楼主,让我再一次获得AC的机会!!!!!!!!!!!!!!!

顺便为了报答,送楼主一个程序:

program gdfs;

var

b,c:longint;

a:string;

i,j:longint;

n:longint;

ch:char;

begin

readln(a);

b:=0; c:=1;

n:=length(a)-2;

for i:=3 to 2+n do

begin

b:=b*10+ord(a[i])-48;

c:=c*10;

end;

readln(ch);

//c:=c*10;

if ch='Y' then

begin

c:=0;

for i:=3 to n+2 do

begin

c:=c*10+9;

end;

end;

j:=b;

for i:=2 to j do

begin

while (b mod i=0) and (c mod i=0) do

begin

b:=b div i;

c:=c div i;

end;

end;

if b-1+c-1<0 then writeln(0) else writeln(b-1+c-1);

readln;

end.

#8 ahfy_zyt@2011-08-24 08:14:00
回复 删除
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD

看了终于AC了,感谢楼主,让我再一次获得AC的机会!!!!!!!!!!!!!!!

顺便为了报答,送楼主一个程序:

program gdfs;

var

b,c:longint;

a:string;

i,j:longint;

n:longint;

ch:char;

begin

readln(a);

b:=0; c:=1;

n:=length(a)-2;

for i:=3 to 2+n do

begin

b:=b*10+ord(a[i])-48;

c:=c*10;

end;

readln(ch);

//c:=c*10;

if ch='Y' then

begin

c:=0;

for i:=3 to n+2 do

begin

c:=c*10+9;

end;

end;

j:=b;

for i:=2 to j do

begin

while (b mod i=0) and (c mod i=0) do

begin

b:=b div i;

c:=c div i;

end;

end;

if b-1+c-1<0 then writeln(0) else writeln(b-1+c-1);

readln;

end.

#9 ahfy_zyt@2011-08-24 08:14:00
回复 删除
Sorry,我不小心多发了一次

#10 charlesi@2012-08-25 01:09:00
回复 删除
用网格状的不反弹可以想到到最后点停留在点(x,y)上,结果应为x-1+y-1。。
查看更多回复
提交回复