Hướng dẫn giải của Even 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

uses math;
var a:ansistring;
    n,i,j,l,t,r:longint;
    re:boolean;
    f:array[0..1000100] of longint;

begin
     readln(t);
     while t>0 do
     begin
          dec(t);
          readln(a);
          n:=length(a);
          if n=0 then re:=true
          else
          begin
               r:=0; l:=1;
               for i:=1 to n do
               begin
                    if i>r then j:=1
                    else j:=min(f[l+r-i+1],r-i+1)+1;
                    while (i+j-1<=n) and (i-j>0) and (a[i+j-1]=a[i-j]) do inc(j);
                    dec(j);
                    f[i]:=j;
                    if i+j-1>r then
                    begin
                         l:=i-j; r:=i+j-1;
                    end;
               end;
               r:=1; i:=1;
               while i<=n do
               begin
                    if (f[i]>0) and (i-f[i]<=r) then
                    begin
                         r:=i+f[i]; i:=r;
                    end
                    else inc(i);
               end;
               re:=r>n;
          end;
          if re then writeln('YES')
          else writeln('NO');
     end;
end.

Code mẫu của ladpro98

#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <climits>
#include <cstdlib>
#include <ctime>
#include <memory.h>
#include <cassert>
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define REP(i, a, b) for(int i = (a); i <=(b); i++)
#define FORD(i, a, b) for(int i = (a); i > (b); i--)
#define REPD(i, a, b) for(int i = (a); i >=(b); i--)
#define TR(it, a) for(typeof((a).begin()) it = (a).begin(); it != (a).end(); ++it)
#define RESET(a, v) memset((a), (v), sizeof((a)))
#define SZ(a) (int((a).size()))
#define ALL(a) (a).begin(), (a).end()
#define PB push_back
#define MP make_pair
#define LL long long
#define LD long double
#define II pair<int, int>
#define X first
#define Y second
#define VI vector<int>
const int N = 1000015;
using namespace std;

string s;
int POW[N], h[N], rh[N];
int n;

int getHash(int l, int r) {
    return h[r] - h[l - 1] * POW[r - l + 1];
}

int getRHash(int l, int r) {
    return rh[l] - rh[r + 1] * POW[r - l + 1];
}

bool isPalin(int l, int r) {
    int mid = l + r >> 1;
    return getHash(l, mid) == getRHash(mid + 1, r);
}

int main() {
    ios :: sync_with_stdio(0); cin.tie(0);
    POW[0] = 1;
    FOR(i, 1, N) POW[i] = POW[i - 1] * 135;
    int nTest;
    cin >> nTest;
    getline(cin, s);
    while (nTest--) {
        getline(cin, s);
        if (s[s.size()-1] == '\r') s.erase(s.size()-1);
        n = SZ(s);
        s = '#' + s;
        REP(i, 1, n) h[i] = h[i - 1] * 135 + s[i];
        rh[n + 1] = 0;
        REPD(i, n, 1) rh[i] = rh[i + 1] * 135 + s[i];
        int l = 1;
        for(int r = 2; r <= n; r += 2)
            if (isPalin(l, r)) l = r + 1;
        cout << (l > n ? "YES\n" : "NO\n");
    }
    return 0;
}

Code mẫu của RR

//Written by RR

{$MODE OBJFPC}
{$R-,Q-}

uses math;
const
  FINP          =       '';
  FOUT          =       '';
  MAXN          =       1000111;
  hkey          =       2147483647;

var
  f1,f2         :       text;
  test,n        :       longint;
  a             :       array[1..MAXN] of longint;

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

procedure closeF;
    begin
      close(f1);
      close(f2);
    end;

procedure inp;
    var
      c:char;
    begin
      n:=0;
      while not seekeoln(f1) do
        begin
          inc(n);
          read(f1,c);
          a[n]:=ord(c);
        end;
      readln(f1);
    end;

function check:boolean;
    var
      i,j:longint;
      r1,r2,lt:longint;
      ok:boolean;
    begin
      i:=1; j:=1;
      repeat
        ok:=false; r1:=a[i]; r2:=a[i]; j:=i; lt:=1;
        while (j<n) do
          begin
            inc(j);
            r1:=(r1 shl 8+a[j]) and hkey;
            lt:=(lt shl 8) and hkey;
            r2:=(r2+a[j]*lt) and hkey;
            if ((j-i) and 1=1) and (r1=r2) then
              begin
                ok:=true;
                i:=j+1;
                break;
              end;
          end;
        if not ok then exit(false);
      until i>n;
      exit(true);
    end;

begin
  openF;
  readln(f1,test);
  for test:=1 to test do
    begin
      inp;
      if n=0 then writeln(f2,'YES')
      else if n and 1=1 then writeln(f2,'NO')
      else if check then writeln(f2,'YES')
      else writeln(f2,'NO');
    end;
  closeF;
end.

Code mẫu của hieult

#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cassert>
#include<ctime>
#include<algorithm>
#include<iterator>
#include<iostream>
#include<cctype>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<list>
//include<conio.h>
#define ep 0.000000001
#define maxn 1000011
#define oo 1000000000
#define ooo 1ll << 62
#define mod 111539786
#define TR(c, it) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); it++)
#define fi first 
#define se second
#define max_size 4
double const PI=4*atan(1);

typedef long long int64;

using namespace std;

typedef pair<int, int> II;
typedef vector<int> VI;
typedef vector<II> VII;
typedef vector<VI> VVI;
typedef vector<VII> VVII;

int f[maxn], n, test;
char s[maxn];

void manacher(char s[]){
    int l = 0, r = -1;
    memset(f, 0, sizeof(f));
    for(int i = 0; i < n; i++){
        int k = (i > r ? 0 : min(f[l + r - i + 1], r - i + 1)) + 1;
        while(i + k - 1 < n && i - k >= 0 && s[i + k - 1] == s[i - k]) k ++;
        f[i] = --k;
        if(i + k - 1 > r)
            r = i + k - 1, l = i - k;
        //printf("%d ",f[i]);
    }
}

int main(){

   // freopen("input.in","r",stdin); 
   // freopen("output.out","w",stdout);
    scanf("%d",&test);
    gets(s);
    while(test--){
        gets(s);
        n = strlen(s);
        if(s[n - 1] == '\r') n--;
        manacher(s);
        int u = n - 1;
        for(int i = n - 1; i >= 0; i--) if(i + f[i] > u) u <?= i - f[i] - 1;
        if( u < 0) printf("YES\n");
        else printf("NO\n");
    }
   // getch();
}

Code mẫu của ll931110

program paldr;
uses math;
const
  input  = '';
  output = '';
  maxn = 1000000;
var
  fi,fo: text;
  rad: array[0..maxn] of longint;
  a: array[0..maxn] of char;
  s: ansistring;
  n: longint;
  i,nTest: longint;

procedure openfile;
begin
  assign(fi, input);
    reset(fi);

  assign(fo, output);
    rewrite(fo);
end;

procedure solve;
var
  i,j,k: longint;
  st,cur: longint;
begin
  readln(fi, s);
  n := length(s);
  for i := 0 to n - 1 do a[i] := s[i + 1];

  if n = 1 then
    begin
      writeln(fo, 'NO');
      exit;
    end;

  i := 0;
  j := 0;
  while i < n do
    begin
      while (i >= j) and (i + 1 + j < n) and (a[i - j] = a[i + 1 + j]) do inc(j);
      rad[i] := j;

      k := 1;
      while (i >= k) and (i + k < n) and (k <= rad[i]) and (rad[i - k] <> rad[i] - k) do
        begin
          rad[i + k] := min(rad[i - k],rad[i] - k);
          inc(k);
        end;

      j := max(j - k,0);
      i := i + k;
    end;

  st := 0;
  cur := 2;
  while cur <= n do
    begin
      if rad[(cur + st) div 2 - 1] * 2 >= cur - st then st := cur;
      cur := cur + 2;
    end;

  if st = n then writeln(fo, 'YES') else writeln(fo, 'NO');
end;

procedure closefile;
begin
  close(fo);
  close(fi);
end;

begin
  openfile;
  readln(fi, nTest);
  for i := 1 to nTest do solve;
  closefile;
end.

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.