P156PROE spoj PTIT – ROUND 6E – Phép dịch

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.

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *