Hướng dẫn giải của Cleaning Robot


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 dx:array[1..4] of shortint=(-1,0,1,0);
      dy:array[1..4] of shortint=(0,1,0,-1);
var m,n,re,i,j,nump,min:longint;
    a:array[1..20,1..20] of char;
    b:array[0..10,0..10] of longint;
    p:array[0..11,0..1] of longint;
    q:array[1..410,0..1] of longint;
    d,dau:array[1..20,1..20] of byte;
    d1:array[1..11] of byte;
    kt:boolean;

function check(x,y:longint):boolean;
begin
     check:=(x>0) and (y>0) and (x<=m) and (y<=n) and (a[x,y]<>'x');
end;

procedure bfs(k,nump:longint);
var num,i,j,x,y,t:longint;
begin
     fillchar(d,sizeof(d),0);
     q[1,0]:=p[k,0]; q[1,1]:=p[k,1];
     d[q[1,0],q[1,1]]:=1;
     num:=1; i:=1; t:=nump;
     repeat
           for j:=1 to 4 do
           begin
                x:=q[i,0]+dx[j]; y:=q[i,1]+dy[j];
                if check(x,y) and (d[x,y]=0) then
                begin
                     inc(num);
                     q[num,0]:=x;
                     q[num,1]:=y;
                     d[x,y]:=d[q[i,0],q[i,1]]+1;
                     if a[x,y]='*' then
                     begin
                          if k=0 then
                          begin
                               dec(t);
                               p[nump-t,0]:=x;
                               p[nump-t,1]:=y;
                               b[0,nump-t]:=d[x,y]-1;
                               b[nump-t,0]:=d[x,y]-1;
                               dau[x,y]:=nump-t;
                          end
                          else
                          begin
                               if dau[x,y]>k then
                               begin
                                    b[k,dau[x,y]]:=d[x,y]-1;
                                    b[dau[x,y],k]:=d[x,y]-1;
                               end;
                          end;
                     end;
                end;
           end;
           inc(i);
     until (i>num) or (t=0);
     kt:=(t=0);
end;

procedure att(i,j:byte);
var k:byte;
begin
     if re>=min then exit;
     if i>nump+1 then
     begin
          if re<min then min:=re;
     end
     else
     begin
          for k:=1 to nump do
              if (d1[k]=0) and (b[k,j]<>0) then
              begin
                   d1[k]:=1;
                   re:=re+b[j,k];
                   att(i+1,k);
                   d1[k]:=0;
                   re:=re-b[j,k];
              end;
     end;
end;

begin
     readln(n,m);
     while n<>0 do
     begin
          nump:=0; min:=maxlongint;
          fillchar(b,sizeof(b),0);
          fillchar(dau,sizeof(dau),0);
          for i:=1 to m do
          begin
               for j:=1 to n do
               begin
                    read(a[i,j]);
                    if a[i,j]='o' then
                    begin
                         p[0,0]:=i; p[0,1]:=j;
                    end;
                    if a[i,j]='*' then inc(nump);
               end;
               readln;
          end;
          bfs(0,nump);
          if not kt then writeln(-1)
          else
          begin
               for i:=1 to nump do bfs(i,nump);
               re:=0;
               fillchar(d1,sizeof(d1),0);
               att(2,0);
               writeln(min);
          end;
          readln(n,m);
     end;
end.

Code mẫu của happyboy99x

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

#define N 22
char mat[N][N];
int dis[N][N][N], f[1 << 11][N], n, m;
int qu[2*N*N], lo, hi, x[12], y[12], dirt, robotx, roboty;
bool vst[N][N];
int d[4][2] = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}};

bool enter() {
    if(scanf("%d%d", &n, &m) == EOF || n == 0 || m == 0) return 0;
    for(int i = 0; i < m; ++i) scanf("%s", mat[i]);
    return 1;
}

void bfs(int i) {
    lo = hi = 0; qu[hi++] = x[i]; qu[hi++] = y[i];
    memset(vst, 0, sizeof vst); vst[x[i]][y[i]] = 1;
    for(int step = 0; lo != hi; ++step) {
        //printf("%d %d\n", lo, hi);
        for(int k = (hi-lo)/2; k > 0; --k) {
            int x = qu[lo++], y = qu[lo++];
            dis[i][x][y] = step;
            //printf("%d %d %d %d\n", i, x, y, step);
            for(int j = 0; j < 4; ++j) {
                int xx = x + d[j][0], yy = y + d[j][1];
                if(xx >= 0 && xx < m && yy >= 0 && yy < n && !vst[xx][yy] && mat[xx][yy] != 'x') {
                    //printf("%d %d %d %d\n", x, y, xx, yy);
                    vst[xx][yy] = 1;
                    qu[hi++] = xx; qu[hi++] = yy;
                    //printf("%d %d\n", lo, hi);
                }
            }
        }
    }
    //printf("BFS(%d)\n", i);
}

inline int F(int state, int t) {
    int & res = f[state][t];
    if(res != -1) return res;
    if(state == 0) return res = dis[t][robotx][roboty];
    res = 1 << 30;
    for(int i = 0; i < dirt; ++i) if(state & 1 << i && dis[t][x[i]][y[i]] != -1)
        res = min(res, max(dis[t][x[i]][y[i]] + F(state & ~(1 << i), i), -1));
    return res;
}

void solve() {
    dirt = 0; bool findRob = 0;
    for(int i = 0; i < m; ++i)
        for(int j = 0; j < n; ++j)
            if(mat[i][j] == '*') { x[dirt] = i; y[dirt++] = j; }
            else if(mat[i][j] == 'o') { robotx = i; roboty = j; findRob = 1; }
    if(dirt == 0) { printf("0\n"); return; }
    if(!findRob) { printf("-1\n"); return; }
    //for(int i = 0; i < dirt; ++i) printf("Dirt: %d %d\n", x[i], y[i]);
    memset(dis, -1, sizeof dis);
    for(int i = 0; i < dirt; ++i) bfs(i);
    /*for(int i = 0; i < dirt; ++i) {
        for(int x = 0; x < m; ++x) {
            for(int y = 0; y < n; ++y) printf("%d ", dis[i][x][y]);
            putchar(10);
        }
        putchar(10);
    }*/
    memset(f, -1, sizeof f);
    int res = 1 << 30;
    for(int i = 0; i < dirt; ++i)
        res = min(res, F((1 << dirt) - 1 & ~(1 << i), i));
    printf("%d\n", res == 1 << 30 ? -1 : res);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    while(enter()) solve();
    return 0;
}

Code mẫu của ladpro98

program mclean;//bfs+bitwise
uses    math;
type    e=record
        x,y,p:longint;
        end;

const   wall = 100;
        free = 0;
        maxn = 22;
        maxV = 1 shl 10;
        fi = '';
        dx:array[1..4] of longint = (1,-1,0,0);
        dy:array[1..4] of longint = (0,0,1,-1);
var     n,m,d:longint;
        s:e;
        a:array[1..maxn,1..maxn] of longint;
        check:array[1..maxn,1..maxn] of boolean;
        visit:array[1..maxn,1..maxn,0..maxV] of boolean;
        res:array[1..maxn,1..maxn,0..maxV] of longint;
        //trace:array[1..maxn,1..maxn,0..maxV] of e;
        trash:array[1..maxn] of e;
        q:array[1..maxn*maxn*maxV] of e;
        inp:text;
        done:boolean;

procedure input;
var
        i,j:longint;
        c:char;
begin
        readln(inp,n,m);
        done:=false;
        if (m=0) then halt;
        d:=0;
        for i:=1 to m do
        begin
                for j:=1 to n do
                begin
                read(inp,c);
                if (c='.') then
                        a[i,j] := free
                else if c='x' then
                        a[i,j] := wall
                else if c='*' then
                begin
                        inc(d);
                        a[i,j] := d;
                        trash[d].x := i;
                        trash[d].y := j;
                end
                else
                if c='o' then
                begin
                        s.x:=i;
                        s.y:=j;
                        a[i,j]:=free;
                end;
                end;
                readln(inp);
        end;

end;

function getbit(i,j:longint):longint;
begin
        exit(i shr (j-1) and 1);
end;


function outBound(i,j:longint):boolean;
begin
        exit(not ((1<=i) and (i<=m) and (1<=j) and (j<=n)));
end;
procedure bfs1;
var     l,r,i,x,y:longint;
        u:e;
begin
        l:=1;r:=1;
        q[1].x:=s.x;
        q[1].y:=s.y;
        check[s.x,s.y]:=true;
        while l<=r do
        begin
                u:=q[l];inc(l);
                for i:=1 to 4 do
                begin
                        x:=u.x+dx[i];
                        y:=u.y+dy[i];
                        if (outBound(x,y)) or (a[x,y] = wall) then continue;
                        if not check[x,y] then
                        begin
                                check[x,y]:=true;
                                inc(r);
                                q[r].x:=x;
                                q[r].y:=y;
                        end;
                end;

        end;
end;

procedure bfs2;
var     l,r,i,x,y,p:longint;
        u:e;
begin
        l:=1;r:=1;
        q[1].x:=s.x;
        q[1].y:=s.y;
        q[1].p:=0;
        visit[s.x,s.y,0]:=true;
        res[s.x,s.y,0]:=0;
        while l<=r do
        begin
                u:=q[l];inc(l);
                for i:=1 to 4 do
                begin
                        x:=u.x+dx[i];
                        y:=u.y+dy[i];
                        if outBound(x,y) or (a[x,y]=wall) then continue;
                        if ((a[x,y]>free) and (getbit(u.p,a[x,y])=0)) then
                                p:=u.p+(1 shl (a[x,y]-1))
                        else    p:=u.p;
                        if not visit[x,y,p] then
                        begin
                                visit[x,y,p]:=true;
                                inc(r);
                                q[r].x:=x;
                                q[r].y:=y;
                                q[r].p:=p;
                                res[x,y,p]:=res[u.x,u.y,u.p]+1;
                                //trace[x,y,p]:=u;
                        end;

                end;

        end;
end;

procedure process;
var     i:longint;
begin
        fillchar(check,sizeof(check),false);
        fillchar(visit,sizeof(visit),false);
        bfs1;
        for i:=1 to d do
        if not check[trash[i].x,trash[i].y] then
        begin
                writeln(-1);
                done:=true;
                exit;
        end
        else
        bfs2;

end;

procedure output;
var     i,r,k,j,t,pos:longint;
        ii:e;
        oup:text;
begin
        if done then exit;
        r:=123456789;
        k:=1 shl d-1;
        for i:=1 to d do
        begin
                if r>res[trash[i].x,trash[i].y,k] then
                begin
                r:=res[trash[i].x,trash[i].y,k];
                pos:=i;
                end;
        end;
        if r=123456789 then writeln(0)
        else
        writeln(r);
        {assign(oup,'mclean.out');
        rewrite(oup);
        i:=trash[pos].x;
        j:=trash[pos].y;
        t:=k;
        while t>0 do
        begin
                writeln(oup,i,' ',j);
                ii:=trace[i,j,t];
                i:=ii.x;
                j:=ii.y;
                t:=ii.p
        end;
        close(oup);}
end;

begin

        assign(inp,fi);
        reset(inp);
        repeat
                input;
                process;
                output;
        until false;
        close(inp);
end.

Code mẫu của RR

{$R+,Q+}
{$Mode objFPC}
const
  FINP='';
  FOUT='';
  MAXN=25;
  oo=1000000000;
  di:array[1..4] of longint=(-1,1,0,0);
  dj:array[1..4] of longint=(0,0,-1,1);
var
  lt2:array[1..11] of longint;
  a:array[1..MAXN,1..MAXN] of char;
  tt,xet:array[1..MAXN,1..MAXN] of longint;
  qu,qv:array[1..MAXN*MAXN] of longint;
  x,y:array[0..10] of longint;
  c:array[0..10,0..10] of longint;
  hpos,d:array[0..MAXN,0..2048] of longint;
  hu,hm:array[1..MAXN*2048] of longint;
  hsize,sl,m,n:longint;
  f1,f2:text;
  ok:boolean;
procedure openF; inline;
begin
  assign(f1,FINP); reset(f1);
  assign(f2,FOUT); rewrite(f2);
end;
procedure closeF; inline;
begin
  close(f1); close(f2);
end;
procedure prepare; inline;
var
  i:longint;
begin
  lt2[1]:=2;
  for i:=2 to 11 do
    lt2[i]:=lt2[i-1]*2;
end;
procedure inp;
var
  i,j:longint;
begin
  sl:=0;
  for i:=1 to m do
    begin
      for j:=1 to n do
        begin
          read(f1,a[i,j]);
          case a[i,j] of
            'o': begin x[0]:=i; y[0]:=j; end;
            '*': begin inc(sl); x[sl]:=i; y[sl]:=j; tt[i,j]:=sl; end;
          end;
        end;
      readln(f1);
    end;
end;
procedure bfs(u,v:longint); inline;
var
  first,last,h,uu,vv:longint;
begin
  first:=1; last:=1; qu[1]:=u; qv[1]:=v;
  xet[u,v]:=1;
  while first<=last do
    begin
      u:=qu[first]; v:=qv[first]; inc(first);
      for h:=1 to 4 do
        begin
          uu:=u+di[h]; vv:=v+dj[h];
          if (uu>0) and (uu<=m) and (vv>0) and (vv<=n) and
             (a[uu,vv]<>'x') and (xet[uu,vv]=0) then
            begin
              xet[uu,vv]:=xet[u,v]+1;
              inc(last); qu[last]:=uu; qv[last]:=vv;
            end;
        end;
    end;
end;
procedure init; inline;
var
  i,j,mask:longint;
begin
  for i:=0 to sl do
    begin
      fillchar(xet,sizeof(xet),0);
      bfs(x[i],y[i]);
      for j:=0 to sl do
        if xet[x[j],y[j]]=0 then ok:=false
        else c[i,j]:=xet[x[j],y[j]]-1;
    end;
end;
procedure swap(var a,b:longint); inline;
var
  temp:longint;
begin
  temp:=a; a:=b; b:=temp;
end;
procedure downHeap(i:longint); inline;
var
  j:longint;
begin
  j:=i shl 1;
  while (j<=hsize) do
    begin
      if (j<hsize) and (d[hu[j+1],hm[j+1]]<d[hu[j],hm[j]]) then inc(j);
      if (d[hu[j],hm[j]]<d[hu[i],hm[i]]) then
        begin
          swap(hpos[hu[i],hm[i]],hpos[hu[j],hm[j]]);
          swap(hu[i],hu[j]);
          swap(hm[i],hm[j]);
        end;
      i:=j; j:=i shl 1;
    end;
end;
procedure upHeap(i:longint); inline;
var
  j:longint;
begin
  j:=i shr 1;
  while (i>1) and (d[hu[i],hm[i]]<d[hu[j],hm[j]]) do
    begin
      swap(hpos[hu[i],hm[i]],hpos[hu[j],hm[j]]);
      swap(hu[i],hu[j]);
      swap(hm[i],hm[j]);
      i:=j; j:=i shr 1;
    end;
end;
procedure push(u,m:longint); inline;
begin
  inc(hsize); hpos[u,m]:=hsize;
  hu[hsize]:=u; hm[hsize]:=m;
  upHeap(hsize);
end;
procedure pop(var u,m:longint); inline;
begin
  u:=hu[1]; m:=hm[1]; hpos[u,m]:=0;
  swap(hu[1],hu[hsize]);
  swap(hm[1],hm[hsize]);
  dec(hsize); downHeap(1);
end;
procedure solve;
var
  u,v,t,tt,i:longint;
begin
  for u:=0 to sl do
  for t:=lt2[sl]-1 downto 0 do
    d[u,t]:=oo;
  fillchar(hpos,sizeof(hpos),0);
  d[0,lt2[sl]-1]:=0;
  hsize:=0;
  push(0,lt2[sl]-1);
  while hsize>0 do
    begin
      pop(u,t);
      if t=0 then
        begin
          writeln(f2,d[u,t]);
          exit;
        end;
      for v:=1 to sl do
      if (t shr (v-1)) and 1=1 then
        begin
          tt:=t and (lt2[sl]-1 shl (v-1)-1);
          if d[v,tt]>d[u,t]+c[u,v] then
            begin
              d[v,tt]:=d[u,t]+c[u,v];
              if hpos[v,tt]=0 then push(v,tt)
              else upHeap(hpos[v,tt]);
            end;
        end;
    end;
end;
begin
  openF;
  prepare;
  readln(f1,n,m);
  while (m>0) and (n>0) do
    begin
      ok:=true;
      inp;
      init;
      if ok then solve
      else writeln(f2,-1);
      readln(f1,n,m);
    end;
  closeF;
end.

Code mẫu của hieult

#include <set>
#include <map>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;
//typedef long double ld;
typedef double ld;
typedef unsigned int ui;
typedef unsigned long long ull;

#define Rep(i,n) for(int i = 0; i < (n); ++i)
#define Repd(i,n) for(int i = (n)-1; i >= 0; --i)
#define For(i,a,b) for(int i = (a); i <= (b); ++i)
#define Ford(i,a,b) for(int i = (a); i >= (b); --i)
#define Fit(i,v) for(int i = (v).begin(); i != (v).end(); ++i)
#define Fitd(i,v) for(int i = (v).rbegin(); i != (v).rend(); ++i)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define sz(a) ((int)(a).size())
#define all(a) (a).begin(), (a).end()
#define ms(a,x) memset(a, x, sizeof(a))
#define nl puts("")
#define sp printf(" ")
#define ok puts("ok")
//#include <conio.h>

template<class F, class T> T convert(F a, int p = -1) { stringstream ss; if (p >= 0) ss << fixed << setprecision(p); ss << a; T r; ss >> r; return r; }
template<class T> void db(T a, int p = -1) { if (p >= 0) cout << fixed << setprecision(p); cout << a << " "; }
template<class T> T gcd(T a, T b) { T r; while (b != 0) { r = a % b; a = b; b = r; } return a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
template<class T> T sqr(T x) { return x * x; }
template<class T> T cube(T x) { return x * x * x; }
template<class T> struct Triple { T x, y, z; Triple() {} Triple(T _x, T _y, T _z) : x(_x), y(_y), z(_z) {} };
template<class T> Triple<T> euclid(T a, T b) { if (b == 0) return Triple<T>(1, 0, a); Triple<T> r = euclid(b, a % b); return Triple<T>(r.y, r.x - a / b * r.y, r.z); }
template<class T> int getbit(T s, int i) { return (s >> i) & 1; }
template<class T> T onbit(T s, int i) { return s | (T(1) << i); }
template<class T> T offbit(T s, int i) { return s & (~(T(1) << i)); }
template<class T> int cntbit(T s) { return s == 0 ? 0 : cntbit(s >> 1) + (s & 1); }
const int bfsz = 1 << 16; char bf[bfsz + 5]; int rsz = 0;int ptr = 0;
char gc() { if (rsz <= 0) { ptr = 0; rsz = fread(bf, 1, bfsz, stdin); if (rsz <= 0) return EOF; } --rsz; return bf[ptr++]; }
void ga(char &c) { c = EOF; while (!isalpha(c)) c = gc(); }
int gs(char s[]) { int l = 0; char c = gc(); while (isspace(c)) c = gc(); while (c != EOF && !isspace(c)) { s[l++] = c; c = gc(); } s[l] = '\0'; return l; }
template<class T> bool gi(T &v) {
    v = 0; char c = gc(); while (c != EOF && c != '-' && !isdigit(c)) c = gc(); if (c == EOF) return false; bool neg = c == '-'; if (neg) c = gc();
    while (isdigit(c)) { v = v * 10 + c - '0'; c = gc(); } if (neg) v = -v; return true;
}

const double PI = 2 * acos(0.0);
const string months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
const int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int dr[] = {0, 0, -1, +1};
const int dc[] = {-1, +1, 0, 0};
const int inf = (int)1e9 + 5;
const ll linf = (ll)1e16 + 5;
const ld eps = ld(1e-9);
const ll mod = 100000007;
typedef pair<int, int> II;

#define maxn 12

II P, A[maxn];
string s[22];
int n, m;
int d[maxn], a[maxn][maxn];
int f[1 << maxn][maxn];
II que[25 * 25];
int size;

bool thoaman(int r, int c){
    return (r >= 0 && r < n && c >= 0 && c < m && s[r][c] != 'x');
}

int bfs(II start, II finish){
    size = 0;
    int flag[25][25];
    ms(flag, -1);
    que[size++] = start;
    flag[start.fi][start.se] = 0;
    int r, c, rr, cc;
    Rep(i, size){
        r = que[i].fi; c = que[i].se;
        if(que[i] == finish) return flag[r][c];
        Rep(h, 4){
            rr = r + dr[h]; cc = c + dc[h];
            if(thoaman(rr, cc) && flag[rr][cc] == -1){
                flag[rr][cc] = flag[r][c] + 1;
                que[size++] = mp(rr, cc);
            }
        }
    }
    return inf;
}

int main()
{
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);

    while(scanf("%d %d", &m, &n) > 0 && n > 0){
        int run = 0;
        Rep(i, n) {
            cin >> s[i];

            Rep(j, m){
                if(s[i][j] == 'o') P = mp(i, j);
                else if(s[i][j] == '*') A[run++] = mp(i, j);
            }

        }
        Rep(i, run) d[i] = bfs(P, A[i]);
        Rep(i, run) Rep(j, run) if(i != j) a[i][j] = bfs(A[i], A[j]);
       // cout << run << endl;
        ms(f, 0x3f);
        int res = inf;
        For(i, 1, (1 << run) - 1) Rep(j, run) if(getbit(i, j)){
            if(cntbit(i) == 1){
                f[i][j] = d[j];
                continue;
            }
            Rep(k, run) if(getbit(i, k)){
                f[i][j] = min(f[i][j], f[i - (1 << j)][k] + a[k][j]);
            }
            if(i == (1 << run) - 1) res = min(res, f[i][j]);
        }
        if(res >= inf) res = -1;
        cout << res << endl;
    }

   // cout << clock() << endl;
    return 0;
}

Code mẫu của ll931110

Program MCLEAN;
        Const
                input  = '';
                output = '';
                  maxn = 20;
                  maxd = 11;
                  maxv = 20000;
        Type
                rec = record
                  x,y: integer;
                end;
        Var
                fi,fo: text;
                check: array[0..maxn + 1,0..maxn + 1] of boolean;
                 free: array[0..maxn + 1,0..maxn + 1] of boolean;
                    c: array[1..maxn,1..maxn] of char;
                    d: array[0..maxn + 1,0..maxn + 1] of integer;
                dx,dy: array[1..4] of integer;
                   st: array[1..15] of rec;
                queue: array[1..maxn * maxn] of rec;
                    a: array[1..maxd,1..maxd] of integer;
                    F: array[0..2500,1..maxd] of integer;
                    n: integer;
                 mark: integer;
                  w,h: integer;

Procedure openfile;
          Begin
                Assign(fi, input);
                        Reset(fi);

                Assign(fo, output);
                        Rewrite(fo);

                dx[1]:= -1;             dy[1]:= 0;
                dx[2]:= 0;              dy[2]:= 1;
                dx[3]:= 1;              dy[3]:= 0;
                dx[4]:= 0;              dy[4]:= -1;
          End;

Procedure init;
          Var
                i,j: integer;
                 ch: char;
          Begin
                Fillchar(check, sizeof(check), false);
                n:= 1;
                For i:= 1 to h do
                  Begin
                    For j:= 1 to w do
                      Begin
                        Read(fi, c[i,j]);
                        If c[i,j] <> 'x' then
                          Begin
                            check[i,j]:= true;
                            If c[i,j] = 'o' then
                              Begin
                                st[1].x:= i;
                                st[1].y:= j;
                              End
                            else if c[i,j] = '*' then
                              Begin
                                inc(n);
                                st[n].x:= i;
                                st[n].y:= j;
                              End;
                          End;
                    End;
                  Readln(fi);
                End;
          End;

Procedure BFS(i: integer);
          Var
                u,v,u1,v1,k,p: integer;
                   front,rear: integer;
          Begin
                free:= check;
                a[i,i]:= 0;
                mark:= n - 1;

                front:= 1;
                rear:= 1;

                queue[1].x:= st[i].x;
                queue[1].y:= st[i].y;
                free[st[i].x,st[i].y]:= false;

                Fillchar(d, sizeof(d), 0);
                Repeat
                  u:= queue[front].x;
                  v:= queue[front].y;
                  inc(front);

                  For k:= 1 to 4 do
                    Begin
                      u1:= u + dx[k];
                      v1:= v + dy[k];

                      If free[u1,v1] and (d[u1,v1] = 0) then
                        Begin
                          inc(rear);
                          queue[rear].x:= u1;
                          queue[rear].y:= v1;
                          d[u1,v1]:= d[u,v] + 1;
                          free[u1,v1]:= false;

                          If c[u1,v1] = 'o' then
                            Begin
                                dec(mark);
                                a[i,1]:= d[u1,v1];
                            End
                          else if c[u1,v1] = '*' then
                            Begin
                              dec(mark);
                              For p:= 2 to n do
                                if (u1 = st[p].x) and (v1 = st[p].y)
                                        then a[i,p]:= d[u1,v1];
                            End;
                       End;
                  End;

                  if mark = 0 then break;
                Until front > rear;
          End;

Procedure optimize;
          Var
                  i,j,k,t: integer;
                      tmp: integer;
                      min: integer;
          Begin
                For i:= 1 to n do
                  Begin
                        BFS(i);
                        If mark <> 0 then
                          Begin
                                Writeln(fo, -1);
                                exit;
                          End;
                  End;

                For i:= 0 to 1 shl n - 1 do
                  For j:= 1 to n do F[i,j]:= maxv;

                F[1,1]:= 0;
                For i:= 2 to 1 shl n - 1 do
                  For j:= 1 to n do
                    if (i and (1 shl (j - 1))) = (1 shl (j - 1)) then
                      Begin
                        t:= i - 1 shl (j - 1);
                        For k:= 1 to n do
                          if (t and (1 shl (k - 1))) = (1 shl (k - 1)) then
                            Begin
                              tmp:= F[t,k] + a[k,j];
                              If F[i,j] > tmp then F[i,j]:= tmp;
                            End;
                      End;

                min:= maxv;
                For i:= 2 to n do if min > F[1 shl n - 1,i]
                                then min:= F[1 shl n - 1,i];
                Writeln(fo, min);
          End;

Procedure closefile;
          Begin
                Close(fo);
                Close(fi);
          End;

Begin
        openfile;

        Repeat
                Readln(fi, w, h);
                If (w <> 0) or (h <> 0) then
                        Begin
                          init;
                          optimize;
                        End;
        Until (w = 0) and (h = 0);

        closefile;
End.

Code mẫu của khuc_tuan

//{$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N+,O+,P+,Q+,R+,S+,T-,U-,V+,W-,X+,Y+,Z1}
// {$APPTYPE CONSOLE}
 {$mode delphi}

uses math;

const
    dx : array[0..3] of integer = (-1,0,1,0);
    dy : array[0..3] of integer = (0,1,0,-1);

var
    res, nj, robot, dem, i, j, m, n : integer;
    a : array[1..22,1..22] of char;
    c, f : array[1..22,1..22] of integer;
    td : array[1..22,1..2] of integer;
    z : array[1..22, 1..22] of integer;
    qx, qy : array[1..1000] of integer;
    g : array[0..10000, 0..13] of integer;

function inside(i,j: integer) : boolean;
begin
    inside := (i>=1) and (i<=m) and (j>=1) and (j<=n);
end;

function bfs(x, y, u, v : integer) : integer;
var
    le, ri, i, j, h : integer;
begin
    fillchar( z, sizeof(z), $1f);
    z[x,y] := 0;
    le := 1;
    ri := 1;
    qx[1] := x;
    qy[1] := y;
    while le <= ri do
    begin
        x := qx[le];
        y := qy[le];
        inc(le);
        for h:=0 to 3 do
        begin
            i := x + dx[h];
            j := y + dy[h];
            if inside(i,j) and (a[i,j]<>'x') and (z[i,j] > z[x,y]+1) then
            begin
                z[i,j] := z[x,y] + 1;
                inc(ri);
                qx[ri] := i;
                qy[ri] := j;
            end;
        end;
    end;
    bfs := z[u,v];
end;

begin
    while true do
    begin
        readln(n, m);
        if (n=0) and (m=0) then break;
        for i:=1 to m do
        begin
            for j:=1 to n do read(a[i,j]);
            readln;
        end;
        dem := 0;
        fillchar( c, sizeof(c), 255);
        robot := -1;
        for i:=1 to m do
            for j:=1 to n do
                if (a[i,j]='o') or (a[i,j]='*') then
                begin
                    inc(dem);
                    c[i,j] := dem;
                    td[dem,1] := i;
                    td[dem,2] := j;
                    if a[i,j]='o' then
                    begin
                        robot := dem;
                    end;
                end;
        for i:=1 to dem do
            for j:= 1 to dem do
                f[i,j] := bfs(td[i,1], td[i,2], td[j,1], td[j,2]);

        fillchar( g, sizeof(g), $1f);

        g[1 shl (robot-1), robot] := 0;
        for i:=1 to (1 shl dem)-1 do
            for j:=1 to dem do
                if g[i,j] <> g[0,0] then
                begin
                    for nj := 1 to dem do if (i and (1 shl (nj-1))) = 0 then
                    begin
                        g[i or (1 shl (nj-1)), nj] := min(  g[i or (1 shl (nj-1)), nj],
                            g[i,j] + f[j,nj]);
                    end;
                end;

        res :=  g[(1 shl dem) - 1, 1];

        for i:=1 to dem do res := min( res, g[ (1 shl dem) - 1, i]);

        if res > 500000000 then writeln(-1)
        else writeln(res);

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