View Full Version : Mình có 1 bài toán thách đố các bạn chuyên tin
forever5pi
25-09-2002, 03:05 PM
Bài toán này cũng đơn giản thôi :
Nhập vào 2 số có độ dài bất kì (<256, giả thiết nhập đúng) ở 2 hệ cơ số nào đó. Hãy thiết kế 1 chương trình chuyển 2 chuỗi số đó sang cùng 1 hệ cơ số khác. Sau đó hãy thực hiện phép nhân 2 số đó, kết quả hiển thị ở 1 hệ cơ số đã chọn.
Hi vọng các bạn cho lời giải tối ưu nhất !
Mapcon
28-09-2002, 07:54 PM
Bác forever5pi ! Em lâu ngày không làm thứ này nên phong độ giảm sút (trước kia vốn cũng kém) mong bác bỏ quá cho em nhé . Tại thấy ko chú nào ở trường lên tiếng em đành phải đáp lời bác vậy .
( Bài này em gõ ở nhà sau đó Post lên đây nên không có dấu mong bác thông cảm nhé . Vài hôm nữa em sẽ Post một bài nói rõ về cái loại này hơn , có chi bác cứ phê bình cho em biết nhé) .
Thuat toan :
De chuyen mot so tu co so S sang co so D thi truoc tien ta can doi so
do sang he co so thap phan (co so 10). Sau do doi tiep so vua thu duoc
sang he co so D can chuyen .
- De chuyenmot so sang co so thap phan (cs 10), ta ap dung cach phan
tich , bieu dien mto so o he cs k thanh tong cac luy thua k .
W = w1w2w3...wn = w1*S^n-1+w2*S^n-2 +...+wn*S^0
= (..((w1*S+w2)*S+w3)..)*S + wn .
Ta se tinh theo do uu tien cac phep toa trong ngoac(vi day la cach giam
toi da so phep
toan ). Vi W co the co gia tri rat lon, nhu vay tung gia tri trong
ngoac cung co the
at lon cho nen ta phai luu tru chung duoi dang xau . De tinh gai tri
bt loai tren ta can thuc hien hai loai phep tinh do la :
+ Nhan mot so lon S (S<=35)
+ Va cong mot so lon voi mot so <=35
- De chuyen mot so tu so so thap phan (cs 10 ) sang mot cs D nao do
ta can chia so do cho D phan du se la ky tu cuoi cung cua bieu dien do
. Sau do ta lai lay thuong cua phep chia vua roi chia tiep cho D ..
Cu lam nhu vay cho toi khi nao thuong thu duoc = 0 . Nhu vay de chuyen
mot so tu cs 10 sang cs D ta phai chia so do cho D (D<=35 )
va lay phan du .
================================
{$Q+,R+}
{$M 16384,0,655360}
Uses Crt;
Const
Max_Coso=35;
Code:String='0123456789ABCDEFGHIKLMNOPQRSTUVWXY';
{ Do chi sd 35 ki tu thuong de ma hoa du lieu cho de quan sat }
Fi='Doicoso.inp';
Fo='Doicoso.out';
Var
W,Coso10:String;
S,D,Dem:Integer;
A:Array[1..1000]of Char; { Mang A luu chuoi ki tu dich}
Procedure Docdulieu;
Var
f:Text;
Begin
Assign(f,Fi);Reset(f);
Readln(f,S,D);
Readln(F,W);
Close(f);
End;
{ * Nhan mot xau ki tu voi mot so lon kieu Integer * }
Function NhanXau(X:String; Number:Integer):String;
Var
Ketqua:String;
k,Nho,Tich:Integer;
Begin
Nho:=0;ketqua:='';
For k:=length(X) downto 1 do
Begin
Tich:=Number*(Pos(X[k],Code)-1)+Nho;
Nho:=Tich div 10;
Ketqua:=Code[Tich mod 10 +1]+Ketqua;
End;
While Nho>0 do
Begin
Ketqua:=Code[Nho mod 10 +1]+Ketqua;
Nho:=Nho div 10;
End;
NhanXau:=Ketqua;
End;
{ * Cong mot xau ki tu voi mot so lon kieu Integer * }
Function CongXau(X:String;Number:Integer):String;
Var
Ketqua:String;
Nho,k,Tong:Integer;
Begin
Ketqua:=X;Nho:=Number;
For k:=Length(X) downto 1 do
Begin
Tong:=Pos(X[k],Code)-1 + Nho;
Nho:= Tong div 10;
Ketqua[k]:=Code[Tong mod 10 +1];
If Nho=0 then Break;
End;
While Nho>0 do
Begin
Ketqua:=Code[Nho mod 10 +1]+Ketqua;
Nho:=Nho div 10;
End;
CongXau:=Ketqua;
End;
{ * Chia mot xau ki tu cho mot so lon kieu Integer * }
Function ChiaXau(X:String; Number:Integer; Var du:Integer):String;
Var
Nho,k:Integer;
Ketqua:String;
Begin
Nho:=0; Ketqua:='';
For k:=1 to Length(X) do
Begin
Nho:=Nho*10+Pos(X[k],Code)-1;
Ketqua:=Ketqua+Code[Nho div Number +1];
Nho:=Nho mod Number;
End;
Du:=Nho;
While (Length(Ketqua)>0) and (Ketqua[1]='0') do
Delete(Ketqua,1,1);
ChiaXau:=Ketqua;
End;
{ * Chuyen mot so lon dang xau tu da cho thanh mot so o he cs 10 * }
Function ChuyenCS10(X:String):String;
Var
Ketqua:String;
k:Integer;
Begin
Ketqua:='';
For k:=1 to Length(X) do
Ketqua:=CongXau(NhanXau(Ketqua,S),Pos(X[k],Code)-1);
ChuyenCS10:=Ketqua;
End;
{ * Chuyen so o he cs 10 thanh so o he cs moi theo yeu cau *}
Procedure ChuyenCSD(X:String);
Var
Du:Integer;
Begin
Dem:=0;
While X <>'' do
Begin
X:=ChiaXau(X,D,Du);
Inc(Dem);
A[Dem]:=Code[du+1];
End;
End;
Procedure Inketqua;
Var
f:Text;
Begin
Assign(f,Fo);Rewrite(f);
While Dem>0 do
Begin
Write(f,A[dem]);
Dec(Dem);
End;
Close(f);
End;
Begin
Docdulieu;
Coso10:=ChuyenCS10(W);
ChuyenCsD(Coso10);
Inketqua;
End.
35 10
XYXYXYXYXY
Mapcon
28-09-2002, 08:01 PM
Bài trên tôi chỉ đặt Max_coso = 35 là chỉ để các kí tự mã hoá tiện cho việc quan sát . nếu cần các bạn có thể thêm các kí tự mã hoá xâu , tuỳ theo thứ tự bằng cách thêm vào xâu Digit='....' .
Tôi chẳng bao giờ đi quá nhanh ! Nhưng cũng chẳng bao giờ đi lùi .
forever5pi
04-10-2002, 01:23 AM
Mapcon cũng ra dáng chuyên nghiệp rồi đấy. Mà nếu chuyển về cùng cơ số sao không chuyển về cơ số 2 để tăng tốc độ tính toán? Các phép tính số học cơ bản(+,-,*,/) đều có thể thực hiện trên hệ cơ số 2 với tốc độ chóng mặt.
Nhân tiện về vấn đề xử lý với số lớn mình cũng post 1 bài để góp vui. Chương trình tính giai thừa với số lớn <=31000 (code bằng pascal thì mình lấy trên tạp chí PCWorld 11/1997).
Program giai_thua;
uses crt,dos;
var
result:array[1..32200] of word;
i,n,leng:word;
count:longint;
timestart,timeend,time:longint;
currenttime:longint absolute $0000:$046c; {ngat dong ho}
PROCEDURE multiply(count:word); {nhan bien result voi count}
var carry,i:word;mul:longint;
begin
carry:=0;
for i:=1 to leng do
begin{xet tung phan tu cua result}
mul:=longint(result[i])*count+carry;
result[i]:=mul mod 10000;
carry :=mul div 10000;
end;
while carry<>0 do
begin
inc(leng);
result[leng]:=carry mod 10000;
carry:=carry div 10000;
end;
end;
FUCTION Format(number:word;count:byte):string;
var s:string;
begin
str(number,s);
while length(s)<count do s:='0' + s;
format:=s;
end;
PROCEDURE write_result;
begin
writeln;
write(n,'! = ',result[leng];
for i:=leng-1 downto 1 do
write(format(result[i],4));
writeln;
BEGIN {main}
clrscr;writeln('Chuong trinh tinh giai thua voi so lon');
write('Nhap n : ');readln(n);
timestart:=currenttime;
leng:=1;
result[1]:=1;
for i:=1 to n do multiply(i);
timeend:=currenttime;
write_result;
count:=length(format(result[leng],0))+longint(leng-1)*4;
writeln('So chu so :',count);
time:=timeend-timestart;
writeln('Thoi gian thuc hien : ',time/18*2 :0:1,' giay');
readln;
END.[/b]