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.
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