Hướng dẫn giải của Bậc Palindrome


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

#include <iostream>
#include <algorithm>
using namespace std;

long long P[222];

void decode(int a[],int n,long long k)
{
    for (int i=0;i<n;i++)
        for (a[i]=0;k>P[n-1-i];a[i]++)
            k-=P[n-1-i];
}

long long countPalin(int n,long long lim)
{
    if (n==1) return 0;
    int a[222],half=(n+1)/2,cmp=0;
    long long res=0;
    decode(a,n,lim);
    for (int i=0;i<half;i++)
        if (a[i]) res+=P[half-1-i]*a[i];
    for (int i=half-1;i>=0 && !cmp;i--)
        if (a[i]>a[n-1-i]) cmp=1;
        else
            if (a[i]<a[n-1-i]) cmp=-1;
    if (cmp<=0) res++;
    return res; 
}

long long findNewK(int n,long long k)
{
    long long last=0,res=k;
    while (1)
    {
        long long x=countPalin(n,res);
        if (res-x>=k) break;
        res+=x-last;
        last=x;
    }
    return res;
}

void solve(int a[],int n,int p,long long k)
{
    if (p) 
    {
        solve(a,(n+1)/2,p-1,k);
        for (int i=0;i<n-1-i;i++) a[n-1-i]=a[i];
        return;
    }
    k=findNewK(n,k);
    decode(a,n,k);
}

int main()
{
    int n,p,a[222];
    long long k;
    cin >> n >> p >> k;
    for (int i=0;i<=n;i++) P[i]=(i?(i>9?P[9]:P[i-1]*26):1);
    solve(a,n,p,k);
    for (int i=0;i<n;i++) cout << char(a[i]+97);
    cout << endl;
}

Code mẫu của ladpro98

#include <bits/stdc++.h>

using namespace std;

const int N = 222;
const long long INF = (long long)1e15;

long long power[N];

string solve(int n, int k) {
    power[0] = 1;
    for (int i = 1; i < n; ++i) power[i] = min(power[i - 1] * 26, INF);
    string s (n, char('a' + k - 1));
    if (n == 1) return s;
    bool canBePalin = 1;
    for (int i = 0; i < n; ++i) {
        long long all = power[n - i - 1];
        for (char c = 'a'; c <= 'z'; ++c) {
            long long palin = 0;
            if (i <= (n - 1) / 2)
                palin = power[(n - 1) / 2 - i];
            else if (canBePalin && c == s[n - i - 1])
                palin = 1;
            long long nonPalin = all;
            if (all != INF) nonPalin -= palin;
            if (k > nonPalin) {
                k -= nonPalin;
            } else {
                s[i] = c;
                if (i > (n - 1) / 2)
                    canBePalin &= c == s[n - i - 1];
                break;
            }
        }
    }
    return s;
}

int main() {
    int n, deg, k;
    cin >> n >> deg >> k;
    int m = n;
    vector<int> save;
    for (int i = 0; i < deg; ++i) {
        save.push_back(m & 1);
        m = (m + 1) / 2;
    }
    string s = solve(m, k);
    for (int i = 0; i < deg; ++i) {
        string t = s;
        reverse(t.begin(), t.end());
        if (save.back())
            s += t.substr(1);
        else
            s += t;
        save.pop_back();
    }
    cout << s << endl;
    return 0;
}

Code mẫu của RR

//Written by Nguyen Thanh Trung
{$R+,Q+}
{$Mode objFPC}
uses math;
const
  FINP          =       '';
  FOUT          =       '';
  MAXN          =       222;
  oo            =       1000000001;
var
  f1,f2         :       text;
  n,p,k         :       longint;
  s             :       string;
  lt26          :       array[0..MAXN] of int64;

procedure openF;
    begin
      assign(f1,FINP); reset(f1);
      assign(f2,FOUT); rewrite(f2);
    end;
procedure closeF;
    begin
      close(f1);
      close(f2);
    end;
procedure build1(l,kk:longint);
    var
      i:longint;
      now:int64;
      c:char;
    begin
      s:='';
      now:=0;
      for i:=1 to l do
        begin
          c:='a';
          while now+lt26[l-i]<=kk do
            begin
              c:=succ(c);
              inc(now,lt26[l-i]);
            end;
          s:=s+c;
        end;
    end;
function equal(a,b:char):longint;
    begin
      if a=b then exit(1) else exit(0);
    end;
procedure build2(l,kk,start:longint;b:boolean);
    var
      i,j:longint;
      now:int64;
      c:char;
    begin
      j:=start;
      now:=0; dec(kk);
      for i:=1 to l do
      begin
        if b then
          begin
            c:='a';
            while now+lt26[l-i]-equal(c,s[j])<=kk do
              begin
                inc(now,lt26[l-i]-equal(c,s[j]));
                c:=succ(c);
              end;
            s:=s+c;
            b:=b and (c=s[j]);
          end
        else //if not b
          begin
            c:='a';
            while now+lt26[l-i]<=kk do
              begin
                c:=succ(c);
                inc(now,lt26[l-i]);
              end;
            s:=s+c;
          end;
        dec(j);
      end;
    end;
procedure build3(n,p,l:longint);
    var
      i,j:longint;
    begin
      if n=l then exit;
      build3((n+1)>>1,p,l);
      if n and 1=1 then
        begin
          j:=length(s)-1;
          for i:=n>>1 downto 1 do
            begin
              s:=s+s[j];
              dec(j);
            end;
        end
      else //n and 1=0
        begin
          j:=length(s);
          for i:=n>>1 downto 1 do
            begin
              s:=s+s[j];
              dec(j);
            end;
        end;
    end;
procedure solve;
    var
      l,i:longint;
      x:int64;
    begin
      l:=n;
      for p:=1 to p do
        l:=(l+1)>>1;
      if l=1 then s:=char(ord('a')+k-1)
      else
        begin
          x:=1;
          for i:=l>>1 downto 1 do begin x*=26; if x>oo then x:=oo; end;
          x-=1;
          build1((l+1)>>1,(k-1) div x);
          k:=k mod x; if k=0 then k:=x;
        end;
      build2(l-(l+1)>>1,k,l>>1,true);
      build3(n,p,l);
      writeln(f2,s);
    end;
procedure init;
    var
      i:longint;
    begin
      lt26[0]:=1;
      for i:=1 to MAXN do
        begin
          lt26[i]:=lt26[i-1]*26;
          if lt26[i]>oo then lt26[i]:=oo;
        end;
    end;

begin
  openF;
  read(f1,n,p,k);
  if n=1 then
    begin
      writeln(char(ord('a')+k-1));
      closeF; halt;
    end;
  init;
  solve;
  closeF;
end.

Code mẫu của ll931110

#include <algorithm>
#include <bitset>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

int n,k,num,len;
int q[202],s[202];
int f[12];
char list[202];

int get(int a,int m)
{
    if (a == 1) return (m - 1);   
    int prefix = (a + 1)/2; 
    int inf = 0,sup = 2000000000,fin = -1;
    while (inf <= sup)
    {
          int med = (inf + sup)/2;
          int tmp = med;
          for (int i = 0; i < a - prefix; i++) tmp /= 26;
          int palin = tmp - 1;          

          tmp = med;
          for (int i = a; i > 0; i--)
          {
              s[i] = tmp % 26; tmp /= 26;
          };
          for (int i = 1; i <= prefix; i++) q[i] = s[i];
          for (int i = prefix + 1; i <= a; i++) q[i] = q[a + 1 - i];
          bool lower = true;
          for (int i = 1; i <= a; i++) if (q[i] != s[i])
          {
              if (q[i] > s[i]) lower = false;
              break;
          };

          if (lower) palin++;
          if (med - palin < num) inf = med + 1; else
          {
             fin = med;  sup = med - 1;
          };
    };
//    cout << fin;
    return fin;
};

int main()
{
//  freopen("lsp.in","r",stdin);
//  freopen("lsp.ou","w",stdout);
    scanf("%d %d %d", &n, &k, &num);

    int len = n;
    for (int i = k; i > 0; i--) len = (len + 1)/2;
    int ret = get(len,num);

    for (int i = len; i > 0; i--)
    {
        q[i] = ret % 26;  ret /= 26;        
    };
    f[k] = n;
    for (int i = k - 1; i > 0; i--) f[i] = (f[i + 1] + 1)/2;

    for (int i = 1; i <= k; i++)
      for (int j = (f[i] + 1)/2 + 1; j <= f[i]; j++) q[j] = q[f[i] + 1 - j];

    for (int i = 1; i <= n; i++) list[i] = q[i] + 'a';
    for (int i = 1; i <= n; i++) printf("%c", list[i]);
};

Code mẫu của skyvn97

#include<cstdio>
#include<iostream>
#define MAX   222
#define FOR(i,a,b) for (int i=(a);i<=(b);i=i+1)
#define FORD(i,b,a) for (int i=(b);i>=(a);i=i-1)
#define REP(i,n) for (int i=0;i<(n);i=i+1)
using namespace std;
typedef long long ll;
const ll INF=(ll)1e9+7LL;
ll pw[MAX];
int len[MAX];
int n,p,l;
char s[MAX];
ll k;
void init(void) {
    cin >> n >> p >> k;
    pw[0]=1LL;
    FOR(i,1,n) pw[i]=min(pw[i-1]*26,INF);   
    len[0]=n;
    FOR(i,1,p) len[i]=(len[i-1]+1)/2;
    l=len[p];
}
void buildstr(void) {
    if (l==1) {
        s[1]=k-1;
        return;
    }
    //printf("Build %d\n",l);
    bool canpalin=true;
    ll nles,ples;
    FOR(i,1,l) {
        //printf("Step %d\n",i);
        REP(j,27) { 
            if (i<=(l+1)/2) nles=min(j*pw[(l+1)/2-i],INF)*(pw[l-(l+1)/2]-1);
            else nles=j*pw[l-i]-(canpalin && j>s[l+1-i]);
            //printf("\tCase %d has %lld les\n",j,nles);
            if (nles>=k) {
                k-=ples;
                s[i]=j-1;
                if (i>(l+1)/2) canpalin=(canpalin && s[i]==s[l+1-i]);
                break;
            }
            else ples=nles;
        }       
    }
}
void buildall(void) {
    int cur=l;
    FORD(i,p-1,0) {
        FOR(j,cur+1,len[i]) s[j]=s[len[i]-j+1];
        cur=len[i];
    }
    FOR(i,1,n) printf("%c",s[i]+'a');   
}
int main(void) {
    ios::sync_with_stdio(false);
    init();
    buildstr();
    buildall();
    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.