Nguồn đề bài: http://www.spoj.com/PTIT/problems/P156PROE/
1. Đề bài P156PROE spoj
Cho trước dãy ký tự:
ABCDEFGHIJKLMNOPQRSTUVWXYZ_.
Phép dịch K trong dãy này được định nghĩa là đẩy một ký tự đi K vị trí.
Ví dụ: phép dịch 1 là ‘A’→’B’, ‘B’→’C’, …, ‘Z’→’_’, ‘_’→’.’, và ‘.’→’A’.
Phép dịch 3 là: ‘A’→’D’, ‘B’→’E’, …, ‘.’→’C’.
Bài toán đặt ra là cho trước số nguyên K và một xâu ký tự, hãy ghi ra kết quả phép dịch K tương ứng của xâu đó sau khi đã đảo ngược thứ tự các chữ cái.
Input
Mỗi bộ test ghi trên một dòng số nguyên 1<=N<=27, tiếp theo là khoảng trống rồi đến xâu S (không quá 40 ký tự và chỉ bao gồm các chữ cái in hoa).
Bộ test cuối cùng có một số 0.
Output
Với mỗi bộ test, ghi ra kết quả phép dịch sau khi đã đảo ngược thứ tự các chữ cái.
Example
Input:
1 ABCD
3 YO_THERE.
1 .DOT
14 ROAD
9 SHIFTING_AND_ROTATING_IS_NOT_ENCRYPTING
2 STRING_TO_BE_CONVERTED
1 SNQZDRQDUDQ
0
Output:
EDCB
CHUHKWBR.
UPEA
ROAD
PWRAYF_LWNHAXWH.RHPWRAJAX_HMWJHPWRAORQ.
FGVTGXPQEAGDAQVAIPKTVU
REVERSE_ROT
2. Thuật toán P156PROE spoj PTIT
– Xây dựng mảng hằng D, là các kí tự lần lượt theo thứ tự ABCDEFGHIJKLMNOPQRSTUVWXYZ_.
– Đọc vào từng test, với mỗi kí tự trong test, ta chuyển sang k kí tự tương ứng.
– Đầu tiên ta xem kí tự cần chuyển là số mấy trong bảng D, gọi là vt, dịch đi k kí tự có nghĩa là kí tự d[vt+k] tuy nhiên trong 1 số trường hợp vt+k sẽ > 28, bạn có thể đặt điều kiệu nếu vt+k > 28 thì kí tự đó sẽ là d[vt+k-28],… ngược lại nếu vt<=28 thì d[vt+k] (ngoài ra bạn có thể đặt mảng hằng D là “ABCDEFGHIJKLMNOPQRSTUVWXYZ_.ABCDEFGHIJKLMNOPQRSTUVWXYZ_.” (có 56 kí tự) nếu không muốn xét điều kiện.)
– sau đó ghi ra xâu ngược theo yêu cầu đề bài.
3. Code tham khảo P156PROE spoj PTIT
const fi=''; D:array[1..28] of char = ('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q' ,'R','S','T','U','V','W','X','Y','Z','_','.'); type data=longint; var F:text; n:data; s:string; function func(c:char; k:data):char; var vt:data; begin if c='_' then vt:=27 else if c='.' then vt:=28 else vt:=ord(c)-64; if vt+k>28 then exit(d[vt+k-28]); exit(d[vt+k]); end; procedure xuli; var i,j:data; begin for i:=length(s) downto 1 do write(func(s[i],n)); writeln; end; procedure docfile; var i,j:data; z:char; begin assign(f,fi); reset(f); repeat read(f,n); if n=0 then break; read(f,z); readln(f,s); xuli; until FALSE; close(f); end; begin docfile; end.