Hướng dẫn giải của Thứ tự từ điển


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này

Code mẫu của flashmt

var test,it,m,n:longint; k,re:int64;
    c:char;
    s:string;
    d,dau:array['a'..'z'] of longint;

procedure rf;
var z:char;
begin
     readln(n,m);
     read(c); s:=''; k:=0; 
     if c='P' then
     begin
          read(z); readln(s);
     end
     else readln(k);
end;

function check:boolean;
var i:longint;
begin
     check:=false;
     fillchar(dau,sizeof(dau),0);
     for i:=1 to m do
         if (ord(s[i])>96+n) or (dau[s[i]]=1) then exit
         else dau[s[i]]:=1;
     check:=true;
end;

function calc(x,y:longint):int64;
var i:longint; r:int64;
begin
     r:=1;
     for i:=1 to x do r:=r*(y-i+1);
     calc:=r;
end;

procedure pr;
var i,t:longint; j:char;
begin
     if not check then writeln('Incorrect data')
     else
     begin
          fillchar(d,sizeof(d),0);
          re:=1;
          for i:=1 to m do
          begin
               t:=0;
               for j:='a' to s[i] do
                   if d[j]=0 then inc(t);
               if t>1 then re:=re+calc(m-i,n-i)*(t-1);
               d[s[i]]:=1;
          end;
          if re<=2000000000 then writeln(re) else writeln('Incorrect data');
     end;
end;

function check1:boolean;
var i:longint; x:int64;
begin
     check1:=true;
     x:=1;
     for i:=1 to m do
         if x>=k then exit else x:=x*(n-i+1);
     check1:=x>=k;
end;

function small(x,y:longint;var u:int64):boolean;
var i:longint; r:int64;
begin
     small:=true; r:=1; 
     for i:=1 to x do
         if r>=k then exit
         else r:=r*(y-i+1);
     if r<k then
     begin
          small:=false; u:=r;
     end;
end;

procedure pr1;
var i:longint; z:char; t,u:int64;
begin
     if not check1 then writeln('Incorrect data')
     else
     begin
          fillchar(d,sizeof(d),0);
          s:='';
          for i:=1 to m do
          begin
               if small(m-i,n-i,u) then t:=1
               else
               begin
                    t:=(k+u-1) div u;
                    k:=(k-1) mod u+1;
               end;
               z:=#96;
               while t>0 do
               begin
                    inc(z);
                    if d[z]=0 then dec(t);
               end;
               s:=s+z;
               d[z]:=1;
          end;
          writeln(s);
     end;
end;

begin
     readln(test);
     for it:=1 to test do
     begin
          rf;
          if c='P' then pr
          else pr1;
     end;
end.

Code mẫu của ladpro98

program NKLEXIC;
uses    math;
const   lim = 2*trunc(1e15);
        fi = '';
var     a:string;
        chk:array[1..30] of boolean;
        Akn:array[0..30,0..30] of int64;
        P:array[0..30] of longint;
        inp:text; c:char;
        n,m,t,tt,res,k:longint;

function ok(i: longint): boolean;
begin
        if (chk[i]) or (i>n) then exit(false);
        chk[i] := true;
end;

procedure Init;
var     n,k:longint;
begin
        for n:=1 to 26 do begin
                Akn[0,n]:=1; Akn[1,n] := n;
                for k:=2 to n do begin
                        Akn[k,n] := Akn[k-1,n]*(n - k + 1);
                        if Akn[k,n] > lim then break;
                end;
        end;
end;

function GetLexic:longint;
var     i, j, t, S:longint;
begin
        for i:=1 to n do chk[i]:=false;
        for i:=1 to m do begin
                P[i] := ord(a[i]) - ord('a') + 1;
                if not ok(P[i]) then exit(-1);
        end;
        S := 0;
        for i:=1 to n do chk[i]:=false;
        for i:=1 to m do begin
                t := 0;
                for j:=1 to P[i]-1 do if not chk[j] then inc(t);
                inc(S, t * Akn[m - i, n - i]);
                chk[P[i]] := true;
        end;
        exit(S+1);
end;

procedure GetStr(k: longint; var a:string);
var     i,j,v,t:longint;
begin
        a:='';
        if (k>Akn[m,n]) or (k>lim) then begin a := 'Incorrect data'; exit; end;
        for i:=1 to n do chk[i] := false;
        for i:=1 to m do begin
                for j := n-1 downto 0 do begin
                        t := 0;
                        for v:=1 to j do
                        if not chk[v] then inc(t);
                        if (not chk[j+1]) and (t*Akn[m-i, n-i] < k) then break;
                end;
                a := a + chr(j+ord('a'));
                chk[j+1] := true;
                dec(k, t*Akn[m-i, n-i]);
        end;
end;

begin
        Init;
        assign(inp,fi);reset(inp);
        readln(inp,t);
        for tt:=1 to t do begin
                readln(inp,n,m);
                read(inp,c);
                if c = 'P' then begin
                        read(inp,c,a);
                        res := GetLexic;
                        if res > 0 then
                        writeln(res)
                        else writeln('Incorrect data');
                end
                else begin
                        readln(inp,k);
                        GetStr(k, a);
                        writeln(a);
                end;
        end;
end.

Code mẫu của RR

{$R+,Q+}
{$Mode objFPC}
uses math;
const
  FINP          =       '';
  FOUT          =       '';
  MAXM          =       30;
  cc            :       string[26]='abcdefghijklmnopqrstuvwxyz';
  base          =       100000000;
  lbase         =       8;

var
  f1,f2:text;

type
  big           =       array[0..10] of int64;
  operator + (a,b:big) c:big;
  var
    i,nho:longint;
  begin
    nho:=0;
    fillchar(c,sizeof(c),0);
    c[0]:=max(a[0],b[0]);
    for i:=1 to c[0] do
      begin
        c[i]:=a[i]+b[i]+nho;
        if c[i]<base then nho:=0 else
        begin nho:=1; c[i]-=base; end;
      end;
    if nho>0 then
      begin
        inc(c[0]);
        c[c[0]]:=nho;
      end;
  end;
  operator - (a,b:big) c:big;
  var
    i,nho:longint;
  begin
    nho:=0;
    fillchar(c,sizeof(c),0);
    c[0]:=a[0];
    for i:=1 to c[0] do
      begin
        c[i]:=a[i]-b[i]-nho;
        if c[i]>=0 then nho:=0
        else begin nho:=1; c[i]+=base; end;
      end;
    while (c[0]>0) and (c[c[0]]=0) do dec(c[0]);
  end;
  operator * (a:big; k:longint) c:big;
  var
    i,nho:longint;
  begin
    nho:=0;
    fillchar(c,sizeof(c),0);
    c[0]:=a[0];
    for i:=1 to c[0] do
      begin
        c[i]:=a[i]*k+nho;
        if c[i]<base then nho:=0
        else begin nho:=c[i] div base; c[i]:=c[i] mod base; end;
      end;
    if nho>0 then
      begin
        inc(c[0]);
        c[c[0]]:=nho;
      end;
  end;
  operator < (a,b:big) c:boolean;
  var
    i:longint;
  begin
    if a[0]<b[0] then exit(true)
    else if a[0]>b[0] then exit(false);
    for i:=a[0] downto 1 do
      if a[i]<b[i] then exit(true)
      else if a[i]>b[i] then exit(false);
    exit(false);
  end;
  procedure print(var a:big);
  var
    i:longint;
    s:string;
  begin
    write(f2,a[a[0]]);
    for i:=a[0]-1 downto 1 do
      begin
        str(a[i],s);
        while length(s)<lbase do s:='0'+s;
        write(f2,s);
      end;
    writeln(f2);
  end;

var
  xet,a:array[0..MAXM*2] of longint;
  c:array[0..MAXM*2,0..MAXM*2+1] of big;
  tt:big;
  n,k:longint;

procedure openF;
    begin
      assign(f1,FINP); reset(f1);
      assign(f2,FOUT); rewrite(f2);
    end;
procedure closeF;
    begin
      close(f1); close(f2);
    end;

procedure init;
    var
      i,j:longint;
    begin
      for i:=0 to MAXM do
        begin
          c[i,0][0]:=1;   c[i,0][1]:=1;
          c[i,i+1][0]:=1; c[i,i+1][1]:=1;
        end;
      for i:=0 to MAXM do
      for j:=1 to i do
          c[i,j]:=c[i,j-1]*(i-j+1);
    end;
procedure solve1;
    var
      s:string;
      u,i:longint;
    begin
      fillchar(a,sizeof(a),0);
      fillchar(xet,sizeof(xet),0);
      for i:=1 to k do
        begin
          u:=1; while xet[u]=1 do inc(u);
          while (c[n-i,k-i]<tt) do
            begin
              tt:=tt-c[n-i,k-i];
              inc(u); while xet[u]=1 do inc(u);
            end;
          xet[u]:=1; a[i]:=u;
        end;
      for i:=1 to k do
        write(f2,cc[a[i]]);
      writeln(f2);
    end;
procedure solve2;
    var
      i,u:longint;
    begin
      fillchar(xet,sizeof(xet),0);
      fillchar(tt,sizeof(tt),0); tt[0]:=1; tt[1]:=1;
      xet[0]:=1;
      for i:=1 to k do
        begin
          u:=1; while xet[u]=1 do inc(u);
          while (u<a[i]) do
            begin
              if xet[u]=0 then tt:=tt+c[n-i,k-i];
              inc(u);
            end;
          xet[a[i]]:=1;
        end;
      print(tt);
    end;
var
  ok:boolean;
  l,test,i,j:longint;
  s:string;
  ch:char;
begin
  openF;
  init;
  readln(f1,test);
  for test:=1 to test do
    begin
      readln(f1,n,k);
      read(f1,ch);
      if ch='P' then
        begin
          read(f1,ch); readln(f1,s);
          while pos(' ',s)>0 do delete(s,pos(' ',s),1);
          for i:=1 to length(s) do
            a[i]:=pos(s[i],cc);
          ok:=true;
          l:=length(s);
          for i:=1 to l do
            if (a[i]<=0) or (a[i]>n) then ok:=false;
          for i:=length(s) downto 2 do
            for j:=i-1 downto 1 do
              if s[i]=s[j] then ok:=false;
          if (n<1) or (n>26) or (k<1) or (k>n) or (length(s)<>k) then ok:=false;
          if not ok then begin writeln(f2,'Incorrect data'); continue; end;
          solve2;
        end
      else
        begin
          read(f1,ch);
          fillchar(tt,sizeof(tt),0);
          readln(f1,tt[1]); tt[0]:=1;
          if tt[1]>base then begin tt[2]:=tt[1] div base; tt[1]:=tt[1] mod base; inc(tt[0]); end;
          if (c[n,k]<tt) or (n<1) or (n>26) or (k<1) or (k>n) then
            begin writeln(f2,'Incorrect data'); continue; end;
          solve1;
        end;
    end;
  closeF;
end.

Code mẫu của ll931110

Program NKLEXIC;
        Const
                input  = '';
                output = '';
        Var
                fi,fo: text;
                k,n,m: longint;

Procedure openfile;
          Begin
                Assign(fi, input);
                        Reset(fi);

                Assign(fo, output);
                        Rewrite(fo);
          End;

Procedure solveP;
          Var
                               s: string;
                      i,calc,x,j: longint;
                           val,p: qword;
                            Free: array[1..26] of boolean;
          Begin
                Readln(fi, s);
                Delete(s, 1, 1);
                Fillchar(Free, sizeof(Free), true);

                val:= 1;
                For i:= 1 to m do
                        Begin
                                x:= ord(s[i]) - 96;

                                If (x > n) or (Free[x] = false) then
                                        Begin
                                                Writeln(fo, 'Incorrect data');
                                                exit;
                                        End;

                                calc:= 0;

                                Free[x]:= false;
                                For j:= 1 to x do if Free[j] then inc(calc);

                                if calc <> 0 then
                                        Begin
                                                p:= 1;
                                                For j:= n - m + 1 to n - i do p:= p * j;
                                                val:= val + qword(calc) * p;
                                        End;

                        End;

                Writeln(fo, val);
          End;

Procedure solveW;
          Var
                      s: string;
              i,j,t,x,y: longint;
                val,inp: qword;
                   Free: array[1..26] of boolean;
          Begin
                Readln(fi, inp);
                Fillchar(Free, sizeof(Free), true);
                s:= '';

                For i:= 1 to m do
                        Begin
                                val:= 1;
                                For j:= n - m + 1 to n - i do
                                        Begin
                                                val:= val * j;
                                                if val > 2000000000 then break;
                                        End;

                                t:= inp div val;
                                If inp mod val = 0 then dec(t);

                                If t >= n then
                                        Begin
                                                Writeln(fo, 'Incorrect data');
                                                exit;
                                        End;

                                inp:= inp - val * t;

                                x:= 0;
                                y:= 0;

                                While x < t + 1 do
                                        Begin
                                                inc(y);
                                                If Free[y] then inc(x);
                                        End;

                                Free[y]:= false;
                                s:= s + chr(y + 96);
                        End;

                Writeln(fo, s);
          End;

Procedure printresult;
          Var
                i: longint;
               ch: char;
          Begin
                Readln(fi, k);

                For i:= 1 to k do
                        Begin
                                Readln(fi, n, m);
                                Read(fi, ch);
                                If ch = 'P' then solveP else solveW;
                        End;
          End;

Procedure closefile;
          Begin
                Close(fo);
                Close(fi);
          End;

Begin
        openfile;
        printresult;
        closefile;
End.

Code mẫu của khuc_tuan

#include <iostream>
using namespace std;

const long long MAXC = 4000000000LL;

int n, m;

long long tinh(int n, int m) {
    long long tmp = 1;
    for(int i=n-m+1;i<=n;++i) {
        tmp *= i;
        if(tmp>=MAXC) tmp = MAXC;
    }
    return tmp; 
}

void process( char * a ) {
    bool b[26];
    int na = strlen(a);
    memset( b, 0, sizeof(b));
    if(na!=m) {
        cout << "Incorrect data" << endl;
        return;
    }
    for(int i=0;i<na;++i) 
        if(a[i]>=n+'a' || a[i]<'a' || b[a[i]-'a']) {
            cout << "Incorrect data" << endl;
            return;
        }
        else b[a[i]-'a'] = true;

    memset( b, 0, sizeof(b));
    int res = 0;
    for(int i=0;i<na;++i) {
        for(int c=0;c<n;++c) {
            if(c==a[i]-'a') break;
            if(!b[c]) res += tinh( n-i-1, m-i-1);
        }
        b[a[i]-'a'] = true;
    }
    cout << res + 1 << endl;
}

void process2(int tt) {
    if(tt>tinh(n,m) || tt<=0) {
        cout << "Incorrect data" << endl;
        return;
    }
    bool b[26];
    char res[30];
    res[m] = 0;
    memset( b, 0, sizeof(b));
    for(int i=0;i<m;++i) {
        for(int c=0;c<n;++c) if(!b[c]) {
            if(tt<=tinh(n-i-1,m-i-1)) {
                res[i] = c + 'a';
                b[c] = true;
                break;
            }
            else tt -= tinh(n-i-1,m-i-1);
        }
    }
    puts(res);
}

int main() {
    int st, t;
    scanf("%d", &st);
    for(t=1;t<=st;++t) {
        scanf("%d%d", &n, &m);
        char buf[100];
        gets(buf);
        gets(buf);
        if(buf[0]=='P') {
            process( buf + 2 );
        }
        else {
            int tt;
            sscanf(buf+2, "%d", &tt);
            process2(tt);
        }
    }
    return 0;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.