Advertisement
a53

nano_PASCAL

a53
Aug 19th, 2017
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.75 KB | None | 0 0
  1. {$H}
  2. program patrat;
  3. uses sysutils;
  4. const dx:qword=1000000000;
  5. kdx=9;// nr. de 0 din dx
  6. nmax=1000;
  7. type nr_mare=record
  8. c:array[0..nmax] of qword;
  9. k:integer;
  10. end;
  11. var a,b,c,d,e:nr_mare;
  12. i,n,l:integer;
  13. fi,fo:text;
  14. s:ansistring;
  15.  
  16. procedure pune_sir_in_nr(var x:nr_mare;s:ansistring);
  17. var i,k,c,l:longint;n:qword;
  18. begin
  19. k:=kdx;
  20. i:=0;{poz. la care pun cifrele}
  21. l:=length(s);
  22. while l>=k do
  23. begin
  24. val(copy(s,l-k+1,k),n,c);{extragem din sir ultimele caractere si le transf. in nr}
  25. x.c[i]:=n;
  26. delete(s,l-k+1,k);
  27. dec(l,k);
  28. inc(i);
  29. end;
  30. if l>0 then
  31. begin
  32. val(copy(s,l-k+1,k),n,c);{extragem din sir ultimele caractere si le transf. in nr}
  33. x.c[i]:=n;
  34. x.k:=i;
  35. end
  36. else x.k:=i-1;
  37. end;
  38.  
  39. procedure pune_nr_in_sir(var s:ansistring;x:nr_mare);
  40. var i:longint;
  41. t:ansistring;
  42. begin
  43. str(x.c[x.k],s);
  44. i:=x.k-1;
  45. while i>=0 do
  46. begin
  47. str(x.c[i],t);// transforman nr. in sir
  48. while length(t)<kdx do t:='0'+t; // cat timp nu are nr. necesar de cifre punem un 0 la inceput
  49. s:=s+t;// adaugam sirul la sirul ce va forma nr.
  50. i:=i-1;
  51. end;
  52. end;
  53.  
  54.  
  55. procedure add(var x,y,z:nr_mare); {adun pe y cu z si pun in x}
  56. var i,km:longint;t:qword;
  57. begin
  58. t:=0;
  59. if y.k>z.k then km:=y.k else km:=z.k; // determinam cel mai lung nr.
  60. x.k:=km;
  61. for i:= 0 to km do
  62. begin
  63. x.c[i]:=y.c[i]+z.c[i]+t;
  64. t:=x.c[i] div dx;
  65. x.c[i]:=x.c[i] mod dx;
  66. end;
  67. if t>0 then // inseamna ce nr. de cifre a crescut prin adunare
  68. begin
  69. inc(x.k);
  70. x.c[x.k]:=t;
  71. end;
  72. end;
  73.  
  74. procedure inmul(var x,y,z:nr_mare);
  75. var i,j,k:longint;t:qword;
  76. begin
  77. fillchar(x,sizeof(x),0);// punem numai 0 in x
  78. x.k:=y.k+z.k;
  79. // facem inmultirea
  80. for i:=0 to y.k do
  81. for j:=0 to z.k do
  82. x.c[i+j]:=x.c[i+j]+y.c[i]*z.c[j];
  83. // "normalizam" numarul
  84. t:=0;
  85. for i:=0 to x.k do
  86. begin
  87. x.c[i]:=x.c[i]+t;
  88. t:=x.c[i] div dx;
  89. x.c[i]:=x.c[i] mod dx;
  90. end;
  91. if t>0 then begin inc(x.k);x.c[x.k]:=t;end;
  92. end;
  93.  
  94. {compara 2 numere mari si return 1 daca primul e mai mare, 0 daca-s egale, -1 daca al doilea e mai mare}
  95. function comp(var x,y:nr_mare):integer;
  96. var r,i:integer;
  97. begin
  98. if x.k>y.k then r:=1
  99. else if x.k<y.k then r:=-1
  100. else
  101. begin
  102. i:=x.k;
  103. while (i>=0)and(x.c[i]=y.c[i]) do dec(i);
  104. if i < 0 then r:=0
  105. else if x.c[i]>y.c[i] then r:=1
  106. else r:=-1;
  107. end;
  108. comp:=r;
  109. end;
  110.  
  111.  
  112. function gen10(n:integer):ansistring;
  113. var s:ansistring;
  114. begin
  115. s:='1';
  116. while(n>1)do begin s:=s+'0';dec(n);end;
  117. gen10:=s;
  118. end;
  119.  
  120. function gen99(n:integer):ansistring;
  121. var s:ansistring;
  122. begin
  123. s:='9';
  124. while(n>1)do begin s:=s+'9';dec(n);end;
  125. gen99:=s;
  126. end;
  127.  
  128.  
  129. procedure div2(var x:nr_mare);{imparte un numar mare la 2}
  130. var t:longint;
  131. i:integer;
  132. begin
  133. t:=0;{transportul e 0 la inceput}
  134. for i:=x.k downto 0 do
  135. begin
  136. x.c[i]:=x.c[i]+t*dx;
  137. t:=x.c[i] mod 2;
  138. x.c[i]:=x.c[i] div 2;
  139. end;
  140. while(x.c[x.k]=0)do dec(x.k);
  141. end;
  142.  
  143. procedure dec_mare( var x:nr_mare);
  144. var i:longint;
  145. begin
  146. dec(x.c[0]);i:=0;
  147. while(x.c[i]<0)do begin
  148. dec(x.c[i+1]);inc(x.c[i],dx);i:=i+1;
  149. end;
  150. while(x.c[x.k]=0)do dec(x.k);
  151. end;
  152.  
  153. procedure inc_mare(var x:nr_mare);
  154. var i:longint;
  155. begin
  156. i:=0;
  157. inc(x.c[0]);
  158. while(x.c[i]=dx)do
  159. begin
  160. x.c[i]:=0;inc(x.c[i+1]);
  161. inc(i);
  162. end;
  163. if i>x.k then inc(x.k);
  164. end;
  165.  
  166.  
  167. function e_patrat(s:ansistring):boolean;
  168. var x:qword;er,l,i:integer;
  169. g:ansistring;f:boolean;
  170. begin
  171. if length(s)<2 then {daca nr. e mic il convertim in nr. "normal"}
  172. begin
  173. val(s,x,er);
  174. e_patrat:=frac(sqrt(x))=0;
  175. end
  176. else {daca e nr. mare incepem sa cautam binar radicalul sau}
  177. begin
  178. l:=length(s); {determinam lungimea}
  179. l:=l+l mod 2; {il aducem la cel mai apropiat nr. par}
  180. l:=l div 2; {determinam lungimea posibilului radical}
  181. g:=gen10(l);
  182. pune_sir_in_nr(a,g);
  183. g:=gen99(l);
  184. pune_sir_in_nr(b,g);
  185. f:=false;{inca nu l-am gasit}
  186. pune_sir_in_nr(e,s);{punem in e nr. de testat}
  187.  
  188. repeat
  189. add(c,a,b);
  190. div2(c); {calculam mijlocul}
  191. inmul(d,c,c);{ridic pe c la patrat}
  192. case comp(d,e) of
  193. 0:f:=true;
  194. 1:begin {d e mai mare ca e, trebuie cautat in stanga}
  195. b:=c;
  196. dec_mare(b);
  197. end;
  198. -1:begin
  199. a:=c;
  200. inc_mare(a);
  201. end;
  202. end;
  203. until f or (comp(a,b)>0); {pana cand gasim sau stanga e mai mare ca dreapta}
  204. e_patrat:=f;
  205. end;
  206. end;
  207.  
  208.  
  209.  
  210.  
  211. BEGIN
  212.  
  213.  
  214. assign(fi,'nano.in');reset(fi);
  215. assign(fo,'nano.out');rewrite(fo);
  216. readln(fi,n);
  217. for i:=1 to n do
  218. begin
  219. readln(fi,l);
  220.  
  221. readln(fi,s);
  222. if l<>length(s) then writeln('NU bate lungimea')
  223. else if e_patrat(s) then writeln(fo,s);
  224.  
  225. end;
  226. close(fi);
  227. close(fo);
  228.  
  229. END.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement