Nguồn đề bài: http://www.spoj.com/PTIT/problems/PTIT121K/
1. Đề bài PTIT121K spoj
Sau những tiết học ban đầu hứng thú với môn Điện tử số về hệ cơ số, MĐ dần thấy nản khi phải đối mặt với các loại mạch và cổng @@. Đầu óc cứ nghĩ đến mấy cái hệ cơ số, MĐ lại nghĩ ra một bài toán khác để thử tài các bạn SV PTIT :D. Bài toán như sau:
Cho một bảng vuông (n x n) ô (2<=n<=100) các ô ghi các số là 0 hoặc 1. Bạn hãy tìm đường đi từ góc trái trên xuống góc phải dưới theo nguyên tắc chỉ được dịch chuyển sang phải và xuống dưới sao cho các số trên đường đi tạo thành một số nhị phân có giá trị lớn nhất.
Input
– Dòng đầu tiên ghi giá trị n
– n dòng tiếp theo, trên mỗi dòng ghi n số 0 hoặc 1 các số này cách nhau ít nhất một khoảng trắng.
Output
– Một số duy nhất là giá trị trong hệ cơ số 16 của số nhị phân được tạo thành ở trên.
Example
Input:
5
1 0 1 1 0
0 0 1 0 1
0 0 1 0 1
1 0 0 1 1
1 1 0 1 0
Output:
176
2. Hướng dẫn PTIT121K spoj PTIT – Đường đi lớn nhất
– áp dụng QHĐ cơ bản, tìm đường đi lớn nhất: C[i,j]:=max(c[i-1,j],c[i,j-1])+chr(a[i,j]+48);
– chuyển đổi hệ cơ số. lưu ý trường hợp có các số 0 ở đầu.
3. code tham khảo PTIT121K spoj PTIT – Đường đi lớn nhất
const fi=''; fo=''; nmax=100; type data=longint; var f:text; A:array[1..nmax,1..nmax] of byte; c:array[0..nmax+1,0..nmax+1] of ansistring; n:data; s:ansistring; procedure docfile; var i,j:data; begin assign(f,fi); reset(f); readln(f,n); for i:=1 to n do for j:=1 to n do read(f,a[i,j]); close(f); end; function max(a,b:ansistring):ansistring; begin if a>b then exit(a); exit(b); end; procedure bpa; var i,j:data; begin for i:=0 to n do begin c[i,0]:=''; c[0,i]:=''; end; for i:=1 to n do for j:=1 to n do C[i,j]:=max(c[i-1,j],c[i,j-1])+chr(a[i,j]+48); s:=c[n,n]; end; function bindec(s:ansistring):data; var i:BYTE; dec:data; begin dec:=0; for i:=0 to 3 do dec:=dec + trunc(exp(ln(2)*i))* (ord(s[4-i])-48); exit(dec); end; function dechex(n:data):ansistring; var du:data; tmp:ansistring; x:char; begin tmp:=''; if n=0 then exit('0'); while n<>0 do begin du:=n mod 16; n:=n div 16; case du of 1..9: x:=chr(du+48); 10: x:='A'; 11: x:='B'; 12: x:='C'; 13: x:='D'; 14: x:='E'; 15: x:='F'; end; tmp:=x+tmp; end; exit(tmp); end; procedure xuli; var i:data; x,z:data; begin while (length(s)>1) and (s[1]='0') do delete(s,1,1); while length(s) mod 4 <>0 do s:='0'+s; z:=-3; for i:=1 to length(s) div 4 do begin inc(z,4); x:=bindec(copy(s,z,4)); write(dechex(x)); end; end; begin docfile; bpa; xuli; end.
Ad ơi, tại sao chỉ di chuyển sang phải và xuống dưới thôi mà công thức lại có c[i-1,j-1] vậy ?
Hi bạn, cảm ơn bạn đã phản hồi. Sau khi kiểm tra lại, mình thấy lấy max c[i-1,j-1] là có phần dư thừa.
Mình sẽ sửa lại phần code trên. Cảm ơn bạn.