[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。否则分解质因数。输出结果的方式在输出样例中会详细给出。每组数据之间空一行。
 

样例输入 

【输入样例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.(*)

原文地址:https://www.cnblogs.com/Catch-22/p/3386801.html