Editorial for VM 09 Bài 01 - Palindrome String


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

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=100100;
var n,re:longint;
    a:array[1..maxn] of char;
    num:array[1..62] of longint;
    b:array[1..62] of longint;
    d,dau:array[1..62] of byte;
    s:array[1..62] of char;
    r:array['0'..'z'] of longint;


procedure init;
var c:char; i:longint;
begin
     for i:=1 to 10 do
     begin
          s[i]:=chr(i+47);
          r[chr(i+47)]:=i;
     end;
     for i:=11 to 36 do
     begin
          s[i]:=chr(i+54);
          r[chr(i+54)]:=i;
     end;
     for i:=37 to 62 do
     begin
          s[i]:=chr(i+60);
          r[chr(i+60)]:=i;
     end;
end;

procedure rf;
begin
     assign(input,fi);
     reset(input);
     n:=0;
     fillchar(num,sizeof(num),0);
     fillchar(d,sizeof(d),0);
     while not eoln do
     begin
          inc(n);
          read(a[n]);
          inc(num[r[a[n]]]);
     end;
     close(input);
end;

procedure pr;
var i,j,max,sum,p,q,t:longint;
begin
     for i:=1 to 62 do b[i]:=i;
     re:=0;
     for i:=1 to n div 2 do
     begin
          p:=r[a[i]]; q:=r[a[n-i+1]];
          if b[p]<>b[q] then
          begin
               d[p]:=1; d[q]:=1;
               t:=b[p];
               for j:=1 to 62 do
                   if b[j]=t then b[j]:=b[q];
          end;
     end;
     for i:=1 to 62 do
         if (num[i]>0) and (d[i]=1) then
         begin
              p:=b[i]; d[i]:=0;
              max:=num[i]; sum:=max;
              for j:=1 to 62 do
                  if (b[j]=p) and (d[j]=1) then
                  begin
                       sum:=sum+num[j];
                       d[j]:=0;
                       if num[j]>max then max:=num[j];
                  end;
              re:=re+sum-max;
         end;
end;

procedure wf;
begin
     assign(output,fo);
     rewrite(output);
     write(re);
     close(output);
end;

begin
     init;
     rf;
     pr;
     wf;
end.

Code mẫu của happyboy99x

#include<cstdio>
#include<cstring>

char s[100000+5];
int c[256], p[256], mx[256];

void init() { for(int i = 0; i < 256; ++i) p[i] = i; }
int get(int u) { return u == p[u] ? u : p[u] = get(p[u]); }

int main() {
    scanf("%s", s);
    for(int i = 0; s[i]; ++i) ++c[s[i]], ++mx[s[i]];
    init();
    for(int i = 0, j = strlen(s) - 1; i < j; ++i, --j) {
        int x = get(s[i]), y = get(s[j]);
        if(x != y) {
            p[p[x]] = p[y]; c[y] += c[x];
            if(mx[x] > mx[y]) mx[y] = mx[x];
            c[x] = 0; mx[x] = 0;
        }
    }
    int res = 0;
    for(int i = 0; i < 256; ++i) res += c[i] - mx[i];
    printf("%d\n", res);
    return 0;
}

Code mẫu của ladpro98

program TOPALIN;
uses    math;
const   fi='';
var     a:ansistring;
        chk:array[1..100] of boolean;
        mat:array[1..100,1..100] of longint;
        w:array[1..100] of longint;
        num:array['0'..'z'] of longint;
        inp:text;
        i,n,res,sum,maxV,t:longint;
        c:char;

procedure dfs(i:longint);
var     j:longint;
begin
        chk[i]:=true;
        inc(sum,w[i]);
        maxV:=max(maxV,w[i]);
        for j:=1 to t do
        if (mat[i,j]=1) and (not chk[j]) then
        dfs(j);
end;

begin
        assign(inp,fi);reset(inp);
        readln(inp,a);close(inp);
        n:=length(a);t:=0;
        for c:='A' to 'z' do begin
                inc(t);num[c]:=t;
        end;
        for c:='0' to '9' do begin
                inc(t);num[c]:=t;
        end;
        for i:=1 to n div 2 do
        if a[i]<>a[n-i+1] then begin
                mat[num[a[i]],num[a[n-i+1]]]:=1;
                mat[num[a[n-i+1]],num[a[i]]]:=1;
        end;
        for i:=1 to n do inc(w[num[a[i]]]);
        for i:=1 to t do
        if not chk[i] then begin
                sum:=0;maxV:=0;
                dfs(i);
                res:=res+sum-maxV;
        end;
        write(res);
end.

Code mẫu của RR

//Written by RR
#include <vector>
#include <set>
#include <algorithm>
#include <string>
#include <cmath>
#include <queue>
#include <map>
#include <iostream>
#include <list>
#include <deque>
#include <cstdio>
#include <cstdlib>

#define MAXN 100111
#define FOR(i,a,b)  for(typeof(a) i=a; i<=b; i++)
#define FORD(i,a,b) for(typeof(a) i=a; i>=b; i--)
#define V vector<long>
#define Q queue<long>
#define S set<long>
#define M map<long,long>
#define FORV(i,v)  for(typeof(v.begin()) i=v.begin(); i!=v.end(); i++)
#define PB push_back
#define SZ(x) ((long) x.size())
#define MP make_pair
#define TWO(x) (long) (1<<x)
#define TWOL(x) (long long) (1<<x)

using namespace std;

typedef long long       ll;
typedef long double     ld;
typedef vector<bool>    vb;
typedef pair<long,long> ii;

long n,freq[300];
char s[MAXN];
V ke[300];

long res;

void inp() {
     scanf("%s",&s);
     n=strlen(s)-1;
     FOR(i,0,n) {
       if (s[i]!=s[n-i]) {
         ke[(long)s[i]].PB((long)s[n-i]);
         ke[(long)s[n-i]].PB((long)s[i]);
       }
     }
     FOR(i,0,n)
       freq[(long)s[i]]++;
}

long xet[MAXN];

void BFS(long start) {
     Q q;
     long u=start;
     q.push(u); xet[u]=start;
     long gtln=u;
     while (!q.empty()) {
           u=q.front(); q.pop();
           FORV(v,ke[u])
             if (xet[*v]==0) {
                             q.push(*v);
                             xet[*v]=start;
                             if (freq[*v]>freq[gtln]) gtln=*v;
             }
     }
     FOR(i,1,299)
       if (xet[i]==start && i!=gtln) res+=freq[i];
}

void solve() {
     FOR(i,1,299)
     if (xet[i]==0)
       if (!ke[i].empty()) BFS(i);
}

int main() {
    inp();
    solve();
    cout<<res<<endl;
    return 0;
}

Code mẫu của hieult

#include <cstdio>
//#include <conio.h>
#include <cstring>

struct chu
{
     int so,a[150];
};

    int tong,maxx;
    int n,c[150][150],d[150],flag[150],KQ = 0;
    char s[100010];
    chu A[150];

void  duyet(int x)
{
     flag[x] = 1;
     tong += d[x];
     if(d[x]>maxx)
         maxx = d[x];
     for(int i = 1;i<=A[x].so;i++)
         if(!flag[A[x].a[i]])
         duyet(A[x].a[i]);
}

int main()
{

    scanf("%s",s);
    n = strlen(s);
    for(int i = 0;i<150;i++)
    {
        A[i].so = 0;
        flag[i] = 0; 
        for(int j = 0;j<150;j++)
             c[i][j] = 0;
    }
    for(int i = 0;i<=(n-1)/2;i++)
    {
         if(i*2==n-1)
              d[s[i]]++;
         else
         {
              d[s[i]]++;
              d[s[n-1-i]]++;
              if(s[i]!=s[n-1-i]&& !c[s[i]][s[n-1-i]])
              {
                  c[s[i]][s[n-1-i]]=1;
                  c[s[n-1-i]][s[i]]=1;
                  A[s[i]].a[++A[s[i]].so] = s[n-1-i];
                  A[s[n-1-i]].a[++A[s[n-1-i]].so] = s[i];
              }
         }
    }
    for(int i = '0';i<='z';i++)  
    {
         if(flag[i] || !d[i])
              continue;
         else
         {
              tong = 0;
              maxx = 0;
              duyet(i);
              KQ += (tong-maxx);
         }
    }

    printf("%d",KQ);
    //getch();
}

Code mẫu của ll931110

{$MODE DELPHI}
{$H+}
program TOPALIN;
const
  input  = '';
  output = '';
  maxk = 62;
var
  s: string;
  a: array[1..maxk,1..maxk] of boolean;
  free: array[1..maxk] of boolean;
  num: array[1..maxk] of integer;
  trans: array['0'..'z'] of integer;
  list: array[1..maxk] of integer;
  n,res,count: integer;

procedure init;
var
  f: text;
begin
  assign(f, input);
    reset(f);

  readln(f, s);
  n := length(s);

  close(f);
end;

procedure DFS(u: integer);
var
  v: integer;
begin
  inc(count);
  list[count] := u;
  free[u] := false;

  for v := 1 to maxk do
    if free[v] and a[u,v] then DFS(v);
end;

procedure solve;
var
  i,j,u,v,sum,max: integer;
  ch: char;
begin
  count := 0;
  for ch := '0' to '9' do
    begin
      inc(count);
      trans[ch] := count;
    end;

  for ch := 'A' to 'Z' do
    begin
      inc(count);
      trans[ch] := count;
    end;

  for ch := 'a' to 'z' do
    begin
      inc(count);
      trans[ch] := count;
    end;

  fillchar(a, sizeof(a), false);

  fillchar(num, sizeof(num), 0);
  for i := 1 to n do
    begin
      u := trans[s[i]];
      v := trans[s[n + 1 - i]];

      inc(num[u]);
      if s[i] <> s[n + 1 - i] then a[u,v] := true;
    end;

  fillchar(free, sizeof(free), true);
  res := 0;

  for i := 1 to maxk do if free[i] then
    begin
      count := 0;
      DFS(i);
      sum := 0;
      max := 0;

      for j := 1 to count do
        begin
          sum := sum + num[list[j]];
          if max < num[list[j]] then max := num[list[j]];
        end;

      res := res + sum - max;
    end;
end;

procedure printresult;
var
  f: text;
begin
  assign(f, output);
    rewrite(f);
    writeln(f, res);
  close(f);
end;

begin
  init;
  solve;
  printresult;
end.

Code mẫu của khuc_tuan

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

using namespace std;

char s[100010];
int n, res, total, cmax;
int C[300], a[300][300], vs[300];

void dfs(int i) {
    vs[i] = true;
    total += C[i];
    cmax = max( cmax, C[i]);
    for(int j=0;j<300;++j) 
        if(!vs[j] && a[i][j]) dfs(j);
}

int main() {
    gets(s);
    n = strlen(s);
    //printf("%d\n", n);
    for(int i=0;i<n;++i) C[s[i]]++;
    for(int i=0,j=n-1;i<j;++i,--j) a[s[i]][s[j]] = a[s[j]][s[i]] = 1;
    for(int i=0;i<300;++i)
        if(!vs[i]) {
            total = cmax = 0;
            dfs(i);
            res += total - cmax;
        }
    // cout << res << endl;
    printf("%d\n", res);
    return 0;
}

Comments

Please read the guidelines before commenting.


There are no comments at the moment.