[Luogu OJ P1619]解一元二次方程的烦恼
题目背景
JosephZheng在写数学作业的预习。他往往使用Casio来帮忙解一元二次方程。但是Casio有一个问题,就是当Δ=b²-4ac为一个大素数或大合数时,其开平方的结果会以小数显示,而不是老师要求的二次根式形式。JosephZheng很是苦恼,一遇到这种情况就要手动解方程。一天他再也忍不住了,于是打开了电脑,编了一个prime程序……于是悲剧的OI们就要跟着疯狂的JosephZheng一起编这个程序,呵呵……
题目描述
废话少说,给你一个大数N(不一定在int64范围内),让你进行素性判断,然后分解质因数。当然,初中数学题不可能有大于int64的数让你判断素性,因此超过范围的数可以忽略不计。为了让程序更加贴心,JosephZheng多了一些要求,会在输入输出中给出具体情况。
输入格式
一个大数N(N为非负整数),其中这个数的各个位数之间可以插入各种符号,例如1234可以为1 - 2alsdkjf3!@¥%!@@@##¥……!¥#-4等。你需要在这一长串乱码中找出这个要判断的数。输入数据可能有多组,如果读到一行没有数字的字串即结束。字符串长度可能大于255。
输出格式
在读入数据之前先输出“Enter the number=”,不要换行。
读入数据完毕后writeln。
然后输出“Prime? ”,问号后有一个空格,但不要换行。
如果是质数则输出“Yes!”否则输出“No!”。此时换行。
若果是质数就halt,若是小于2的数则在输出“No!”后也halt。若是合数则分解质因数。如果该数大于四千万则输出“The number is too large!”,然后halt。否则分解质因数。输出结果的方式在输出样例中会详细给出。每组数据之间空一行。
读入数据完毕后writeln。
然后输出“Prime? ”,问号后有一个空格,但不要换行。
如果是质数则输出“Yes!”否则输出“No!”。此时换行。
若果是质数就halt,若是小于2的数则在输出“No!”后也halt。若是合数则分解质因数。如果该数大于四千万则输出“The number is too large!”,然后halt。否则分解质因数。输出结果的方式在输出样例中会详细给出。每组数据之间空一行。
样例输入
【输入样例1】
4
eed
【输入样例2】
2
end
【输入样例3】
-1
adfs
【输入样例4】
1234###24#@13#@¥!1
hehe
【输入样例5】
1.5
1
1234324123512343123
@~@~@~@
样例输出
【输出样例1】
Enter the number=
Prime? No!
4=2^2
Enter the number=
【输出样例2】
Enter the number=
Prime? Yes!
Enter the number=
【输出样例3】
Enter the number=
Prime? No!
Enter the number=
【输出样例4】
Enter the number=
Prime? No!
The number is too large!
Enter the number=
【输出样例5】
Enter the number=
Prime? No!
15=3^1*5^1
Enter the number=
Prime? No!
Enter the number=
Prime? No!
The number is too large!
Enter the number=
此题本水题,只是很烦人、、、
以下来自本人题解:
个人认为题里的一堆halt除了判断输出末尾那个应该是halt,
别的(“若果是质数就halt,若是小于2的数则在输出“No!”后也halt。若是合数则分解质因数。如果该数大于四千万则输出“The number is too large!”,然后halt。”)
都不该那么写。
话说读入你本也可以写成while not eof do的、、
1 Var 2 st:AnsiSTring; 3 ch:char; 4 Tt:Int64; 5 Function Prime(Tt:int64):Boolean; 6 //注意细节,一开始习惯性写成Tt:longint,然后202半天不知道为什么 7 Var 8 i:longint; 9 Begin 10 if Tt<=1 Then Exit(False); 11 For i:=2 to Trunc(Sqrt(Tt)) do 12 if Tt mod i=0 then Exit(False); 13 Exit(True); 14 End; 15 Procedure Task(); 16 Var 17 i,j:longint; 18 xx:longint; 19 Flag:boolean; 20 Begin 21 Write(Tt,'='); 22 For i:=2 to Tt do 23 Begin 24 Flag:=False; 25 if Tt<=1 Then Break; 26 xx:=0; 27 While Tt Mod i=0 Do 28 Begin 29 Inc(xx); 30 Tt:=Tt Div i; 31 Flag:=True; 32 End; 33 if Flag Then 34 Begin 35 Write(i,'^',xx); 36 Break;//输出一个后退出for循环,进入带*输出阶段 37 End; 38 End; 39 {一开始想怎么判断前面是否有*,后来发现分成两端是个不错的方法,方便快捷一次见效不反复} 40 For j:=i to Tt do 41 Begin 42 Flag:=False; 43 if Tt<=1 Then Break; 44 xx:=0; 45 While Tt Mod j=0 Do 46 Begin 47 Inc(xx); 48 Tt:=Tt Div j; 49 Flag:=True; 50 End; 51 if Flag Then 52 Begin 53 Write('*',j,'^',xx); 54 {下面的标程是拿数组存的,我感觉直接输出比较好,省空间,尤其是解决了*号问题之后、、、} 55 End; 56 End; 57 Writeln; 58 End; 59 Begin 60 While True do //话说原来while true do 都写成一些好玩的东西、、谁有兴趣自己改着玩啊、、 61 Begin 62 sT:=''; 63 Write('Enter the number='); 64 While Not Eoln do 65 Begin 66 Read(ch); 67 if ch in ['0'..'9'] then 68 st:=st+ch; 69 End; 70 Readln; 71 Writeln; 72 if st='' Then Halt; 73 Write('Prime? '); 74 Val(st,Tt);//字符变数字 75 if Prime(Tt) Then Writeln('Yes!') 76 Else 77 Begin 78 Writeln('No!'); 79 if Tt>40000000 Then Writeln('The number is too large!') 80 //数清楚0,我一开始写成4000000了、、、、、 81 else if Tt>=2 Then Task; 82 End; 83 Writeln; 84 End; 85 End.
这个题交了4次才AC,第一次是Task()里面循环写了个如果Tt<=1 Then Exit 导致没有回车换行,0
第二次是又发现Prime(Tt)里面范围int64的问题,20
第三次是又发现40000000写成了4000000,80
第四次AC、、
总体说,确实是水题,但也确实很考察细心、、、、、
各位认真了···
(*)Done By Catch-22.S.Iris in Lensent CST Team.(*)