Hướng dẫn giải của Đếm chuỗi đối xứng


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

const fi='';
      fo='';
      maxn=121;
      base=100000000;
      digit=8;
type bignum=array[0..10] of longint;
var n:longint;
    s:string;
    f:array[1..maxn,1..maxn] of bignum;

procedure rf;
var i:longint;
begin
     assign(input,fi);
     reset(input);
     read(s);
     n:=length(s);
     fillchar(f,sizeof(f),0);
     close(input);
end;

procedure plus(var a:bignum;b,c:bignum);
var i,mem,max:longint;
begin
     if b[0]>c[0] then max:=b[0] else max:=c[0];
     mem:=0;
     for i:=1 to max do
     begin
          a[i]:=(b[i]+c[i]+mem) mod base;
          mem:=(c[i]+b[i]+mem) div base;
     end;
     if mem>0 then
     begin
          inc(max);
          a[max]:=mem;
     end;
     a[0]:=max;
end;

procedure minus(var a:bignum;b:bignum);
var i,mem,max:longint;
begin
     max:=a[0];
     mem:=0;
     for i:=1 to max do
         if a[i]-b[i]-mem<0 then
         begin
              a[i]:=a[i]+base-b[i]-mem;
              mem:=1;
         end
         else
         begin
              a[i]:=a[i]-b[i]-mem;
              mem:=0;
         end;
     i:=max;
     while (i>1) and (a[i]=0) do dec(i);
     a[0]:=i;
end;

procedure calc(l,r:longint);
var t:bignum;
begin
     if l=r then
     begin
          f[l,l,0]:=1; f[l,l,1]:=1;
          exit;
     end;
     if f[l,r-1,0]=0 then calc(l,r-1);
     if f[l+1,r,0]=0 then calc(l+1,r);
     plus(f[l,r],f[l,r-1],f[l+1,r]);
     if s[l]=s[r] then
     begin
          fillchar(t,sizeof(t),0);
          t[0]:=1; t[1]:=1;
          plus(f[l,r],f[l,r],t);
     end
     else
     begin
          if (l+1<=r-1) and (f[l+1,r-1,0]=0) then calc(l+1,r-1);
          minus(f[l,r],f[l+1,r-1]);
     end;
end;

procedure pr;
var i,j:longint;
begin
     calc(1,n);
end;

procedure wf;
var i,j,t:longint; s:string; re:bignum;
begin
     assign(output,fo);
     rewrite(output);
     re:=f[1,n];
     for i:=re[0] downto 1 do
     begin
          if i<re[0] then
          begin
               str(re[i],s);
               t:=length(s);
               for j:=t+1 to digit do write(0);
          end;
          write(re[i]);
     end;
     close(output);
end;

begin
     rf;
     pr;
     wf;
end.

Code mẫu của happyboy99x

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

const int BASE = 1000000000, MAX_DIGIT = 5, LOG_BASE = 9, N = 120;
struct BigInteger {
    int d[MAX_DIGIT], n;

    void operator = (const int &x) {
        memset(d, 0, sizeof d); n = 0;
        for(int t = x; t != 0; t /= BASE)
            d[n++] = t % BASE;
    }

    void operator += (const BigInteger &a) {
        int rem = 0; n = max(n, a.n);
        for(int i = 0; i < n; ++i) {
            int p = d[i] + a.d[i] + rem;
            if(p >= BASE) d[i] = p - BASE, rem = 1;
            else d[i] = p, rem = 0;
        }
        if(rem) d[n++] = rem;
    }

    void operator -= (const BigInteger &a) {
        int rem = 0;
        for(int i = 0; i < n; ++i) {
            int p = d[i] - a.d[i] - rem;
            if(p < 0) d[i] = p + BASE, rem = 1;
            else d[i] = p, rem = 0;
        }
        while(n > 0 && d[n-1] == 0) --n;
    }

    void print() {
        printf("%d", d[n-1]);
        for(int i = n-2; i >= 0; --i)
            printf("%0*d", LOG_BASE, d[i]);
        printf("\n");
    }
} f[N][N], ONE;
char s[N+1];

int main() {
    ONE = 1; scanf("%s", s); int n = strlen(s);
    for(int i = 0; i < n; ++i) f[i][i] = ONE;
    for(int l = 2; l <= n; ++l)
        for(int i = 0, j = l - 1; j < n; ++i, ++j) {
            f[i][j] = f[i+1][j];
            f[i][j] += f[i][j-1];
            if(s[i] == s[j]) f[i][j] += ONE;
            else f[i][j] -= f[i+1][j-1];
        }
    f[0][n-1].print();
    return 0;
}

Code mẫu của ladpro98

program qbpal;
uses    math;
type    big=string;

const   fi='';
var     s:string;
        f:array[1..123,1..123] of big;
        check:array[1..123,1..123] of boolean;
        n:longint;

procedure input;
var     inp:text;
begin
        assign(inp,fi);
        reset(inp);
        readln(inp,s);
        close(inp);
        n:=length(s);
end;

function plus(a,b:big):big;
var     c:big;
        i,carry,s:longint;
begin
        carry:=0;c:='';
        while  length(a)<length(b) do a:='0'+a;
        while  length(b)<length(a) do b:='0'+b;
        for i:=length(a) downto 1 do
        begin
                s:=ord(a[i])+ord(b[i])+carry-96;
                c:=chr(s mod 10+48) +c;
                carry:=s div 10;
        end;
        if carry>0 then c:='1'+c;
        exit(c);
end;

function sub(a,b:big):big;
var     c:big;
        s,br,i:longint;
begin
        br:=0;
        c:='';
        while  length(a)<length(b) do a:='0'+a;
        while  length(b)<length(a) do b:='0'+b;
        for i:=length(a) downto 1 do
        begin
                s:=ord(a[i])-ord(b[i])-br;
                if s<0 then
                begin
                        s:=s+10;
                        br:=1;
                end
                else
                br:=0;
                c:=chr(s+48)+c;
        end;
        while (length(c)>1) and (c[1]='0') do delete(c,1,1);
        exit(c);
end;

procedure init;
var     i,j:longint;
begin
        for i:=1 to n do
        begin
                f[i,i]:='1';
                check[i,i]:=true;
        end;
        for i:=1 to n-1 do
        begin
                if s[i]=s[i+1] then
                begin
                        f[i,i+1]:='3';
                        check[i,i+1]:=true;
                end
                else
                begin
                        f[i,i+1]:='2';
                        check[i,i+1]:=true;
                end;
        end;
end;

function dp(i,j:longint):big;
var     k:longint;
begin
        if check[i,j] then exit(f[i,j]);
        check[i,j]:=true;
        if s[i]=s[j] then
        f[i,j]:=plus(plus(dp(i+1,j),dp(i,j-1)),'1')
        else
        f[i,j]:=sub(plus(dp(i+1,j),dp(i,j-1)),dp(i+1,j-1));
        exit(f[i,j]);
end;

begin
        input;
        init;
        write(dp(1,n));
end.

Code mẫu của RR

{$R+,Q+}
uses math;
const
  MAXN=200;
  oo=10;
type
  bigNum=array[0..MAXN] of longint;
var
  s:string;
  n:longint;
  d:array[0..MAXN,0..MAXN] of bigNum;
operator +(a,b:bigNum) c:bigNum;
var
  nho,i:longint;
begin
  nho:=0;
  fillchar(c,sizeof(c),0); c[0]:=max(a[0],b[0]);
  for i:=MAXN downto MAXN-c[0]+1 do
    begin
      c[i]:=a[i]+b[i]+nho;
      nho:=c[i] div oo;
      c[i]:=c[i] mod oo;
    end;
  if nho>0 then
    begin
      inc(c[0]);
      c[MAXN-c[0]+1]:=nho;
    end;
end;
operator -(a,b:bigNum) c:bigNum;
var
  nho,i:longint;
begin
  nho:=0;
  fillchar(c,sizeof(c),0); c[0]:=a[0];
  for i:=MAXN downto MAXN-c[0]+1 do
    begin
      c[i]:=a[i]-b[i]-nho;
      if c[i]<0 then
        begin
          nho:=1;
          c[i]:=c[i]+oo;
        end
      else nho:=0;
    end;
  while (c[0]>0) and (c[MAXN-c[0]+1]=0) do dec(c[0]);
end;
procedure solve;
var
  i,j,k:longint;
  a:bigNum;
begin
  fillchar(a,sizeof(a),0);
  a[0]:=1; a[200]:=1;
  for i:=1 to n do d[i,i]:=a;
  for k:=1 to n do
  for i:=1 to n-k do
    begin
      j:=i+k;
      if s[i]=s[j] then d[i,j]:=d[i,j-1]+d[i+1,j]+a
      else d[i,j]:=d[i,j-1]+d[i+1,j]-d[i+1,j-1];
    end;
end;
procedure print(a:bigNum);
var
  i:longint;
  s:string;
begin
  if a[0]=0 then begin writeln(0); exit; end;
  write(a[MAXN-a[0]+1]);
  for i:=MAXN-a[0]+2 to MAXN do write(a[i]);
  writeln;
end;
begin
  readln(s); n:=length(s);
  solve;
  print(d[1,n]);
end.

Code mẫu của hieult

#include <cstdio>
#include <cstring>
//#include <conio.h>
#define base 100000000

struct solon
{
     int so;
     int a[40];
};

solon f[122][122],T;
char s[122];
int n;

solon tong (solon A,solon B)
{
      int du = 0;
      solon C;
      if(A.so<B.so)
      {
           C = A;
           A = B;
           B = C;
      }
      for(int i = B.so+1;i<=A.so;i++) B.a[i] = 0;
      C.so = A.so;
      for(int i = 1;i<=A.so;i++)
      {
          C.a[i] = (A.a[i]+B.a[i]+du)%base;
          du = (A.a[i]+B.a[i]+du)/base;
      }
      if(du>0) {C.so++; C.a[C.so] = du;}
      return C;
}

solon hieu(solon A,solon B)
{
      int du = 0;
      solon C;
      for(int i = B.so+1;i<=A.so;i++) B.a[i] = 0;
      C.so = A.so;
      for(int i = 1;i<=A.so;i++)
      {
           C.a[i] = (A.a[i]-B.a[i]-du);
           if(C.a[i]<0) {
                   C.a[i] += base;
                   du = 1;
           }
      }
      while(C.a[C.so]==0 && C.so>1) C.so--;
      return C;
}

void print(solon A)
{
      printf("%d",A.a[A.so]);
     for(int i = A.so-1;i>=1;i--)
         printf("%08d",A.a[i]);
}

bool doixung(int i,int j)
{
     if(j-i<2)
         return (s[i]==s[j]);
     if(s[i]!=s[j]) return false;
     else return doixung(i+1,j-1);
}

int main()
{
     // freopen("QBPAL.in","r",stdin);
      scanf("%s",s);
      n = strlen(s);
      T.so = 1; T.a[1] = 1;
      for(int i = 0;i<n;i++)
      {
           f[i][i] = T;
           f[i+1][i].so = 1;
           f[i+1][i].a[1] = 0;
      }
      for(int k = 1;k<n;k++)
           for(int i =0;i+k<n;i++)
           {
                int j = i+k;
                f[i][j] = tong(f[i+1][j],f[i][j-1]);
                if(s[i]==s[j]) f[i][j] = tong(f[i][j],T);
                else f[i][j] = hieu(f[i][j],f[i+1][j-1]); 
              //  printf("%d %d %d\n",i,j,f[i][j].a[1]);
           }
      //if(doixung(0,n-1)) f[0][n-1] = hieu(f[0][n-1],T);
      print(f[0][n-1]);  
    //  getch(); 
}

Code mẫu của khuc_tuan

s = raw_input()
n = len(s)

F = [[-1 for i in range(n)] for j in range(n)]

def calc(a,b):
    if a>b:
        return 1
    if a==b:
        return 2
    if F[a][b]!=-1:
        return F[a][b]
    res = 0
    res = calc(a+1,b) + calc(a,b-1) - calc(a+1,b-1)
    if s[a]==s[b]:
        res += calc(a+1,b-1)
    F[a][b] = res
    return res

print calc(0,n-1) - 1

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.