Hướng dẫn giải của VM 08 Bài 19 - Cúp FA


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 maxn=300;
      p:array[1..8] of longint=(2,4,8,16,32,64,128,256);
var n:longint;
    a:array[1..maxn,1..maxn] of real;
    b:array[1..8,1..maxn] of real;
    re:array[1..maxn] of longint;
    t:array[1..maxn] of real;

procedure rf;
var i,j,t:longint;
begin
     readln(n);
     for i:=1 to p[n] do
     begin
          for j:=1 to p[n] do
          begin
               read(t);
               a[i,j]:=t/100;
          end;
          readln;
     end;
end;

procedure calc(rnd,team:longint);
var i,j,l,r,lm,rm:longint;
begin
     l:=((team-1) div p[rnd])*p[rnd]+1;
     r:=l+p[rnd]-1;
     lm:=((team-1) div p[rnd-1])*p[rnd-1]+1;
     rm:=lm+p[rnd-1]-1;
     for i:=l to r do
         if (i<lm) or (i>rm) then
            b[rnd,team]:=b[rnd,team]+b[rnd-1,team]*b[rnd-1,i]*a[team,i];
end;

procedure sort(l,r:longint);
var i,j,z:longint; x,y:real;
begin
     i:=l; j:=r; x:=t[(i+j) div 2];
     repeat
           while t[i]<x do inc(i);
           while t[j]>x do dec(j);
           if i<=j then
           begin
                y:=t[i]; t[i]:=t[j]; t[j]:=y;
                z:=re[i]; re[i]:=re[j]; re[j]:=z;
                inc(i); dec(j);
           end;
     until i>j;
     if i<r then sort(i,r);
     if l<j then sort(l,j);
end;

procedure pr;
var i,j:longint;
begin
     fillchar(b,sizeof(b),0);
     for i:=1 to p[n] do
     begin
          if i mod 2 = 1 then b[1,i]:=a[i,i+1]
          else b[1,i]:=a[i,i-1];
     end;
     for i:=2 to 8 do
         for j:=1 to p[n] do
             calc(i,j);
     for i:=1 to p[n] do
     begin
          t[i]:=b[n,i];
          re[i]:=i;
     end;
     sort(1,p[n]);
end;

procedure wf;
var i:longint;
begin
     for i:=p[n] downto 1 do
         writeln(re[i]);
end;

begin
     rf;
     pr;
     wf;
end.

Code mẫu của happyboy99x

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

const int N = 8;
int winProb[1 << N][1 << N];
double comeProb[N + 1][1 << N];

int main() {
#ifndef ONLINE_JUDGE
    freopen("FACUP.inp", "r", stdin);
#endif
    ios::sync_with_stdio(false);
    int n; cin >> n;
    int numTeam = 1 << n;
    for(int i = 0; i < numTeam; ++i) {
        for(int j = 0; j < numTeam; ++j) {
            cin >> winProb[i][j];
        }
    }
    fill_n(comeProb[0], numTeam, 1);
    for(int round = 0; round < n; ++round) {
        for(int team = 0; team < numTeam; ++team) {
            int opponentForm = (team & ~((1 << round) - 1)) ^ (1 << round);
            for(int i = 0; i < 1 << round; ++i) {
                int opponent = opponentForm | i;
                comeProb[round + 1][team] += winProb[team][opponent] * comeProb[round][opponent];
            }
            comeProb[round + 1][team] *= comeProb[round][team] / 100;
        }
    }
//    for(int round = 0; round <= n; ++round) {
//        for(int team = 0; team < numTeam; ++team) {
//            cerr << comeProb[round][team] << ' ';
//        }
//        cerr << '\n';
//    }
    vector<pair<double, int> > v (numTeam);
    for(int i = 0; i < numTeam; ++i) {
        v[i] = make_pair(-comeProb[n][i], i);
    }
    sort(v.begin(), v.end());
    for(int i = 0; i < numTeam; ++i) {
        printf("%d\n", v[i].second + 1);
    }
    return 0;
}

Code mẫu của ladpro98

#include <cstdio>
#include <algorithm>
#include <vector>
#define di pair<double, int>
const int N = 9;
const int M = 1 << N;
using namespace std;
int a[M][M];
double F[M][N];
int m, n;
vector<di> b;

int main()
{
    scanf("%d", &n); m = 1 << n;
    int i, j, k, t, pos, lim;
    for(i=1; i<=m; i++) for(j=1; j<=m; j++) scanf("%d", &a[i][j]);
    for(i=1; i<=m; i++) F[i][0] = 1;
    for(k=0; k<n; k++) for(i=1; i<=m; i++) {
        t = 1 << k;
        pos = i / t; if (i % t > 0) pos++;
        if (pos & 1) {
            lim = (pos + 1) * t;
            for(j = lim; j > (lim - t); j--)
                F[i][k+1] += F[i][k] * F[j][k] * a[i][j] / 100;
        }
        else {
            lim = (pos - 1) * t;
            for(j = lim; j > (lim - t); j--)
                F[i][k+1] += F[i][k] * F[j][k] * a[i][j] / 100;
        }
    }
    for(i=1; i<=m; i++) b.push_back(di(1 - F[i][n], i));
    sort(b.begin(), b.end());
    for(i=0; i<b.size(); i++) printf("%d\n", b[i].second);
    return 0;
}

Code mẫu của RR

//Written by RR
{$R+,Q+,N+}
{$Mode objfpc}
{$inline on}

uses math;
const
  FINP          =       '';
  FOUT          =       '';
  MAXN          =       256;

var
  f1,f2         :       text;
  n,sr          :       longint;
  p             :       array[0..MAXN,0..MAXN] of extended;
  ind           :       array[1..MAXN] of longint;
  f             :       array[0..MAXN,0..8] of extended;

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
      i,j:longint;
    begin
      read(f1,sr);
      n:=1<<sr;
      for i:=0 to n-1 do
      for j:=0 to n-1 do
        begin
          read(f1,p[i,j]);
          p[i,j]:=p[i,j]/100.0;
        end;
    end;

procedure solve;
    var
      r,i,j:longint;
    begin
      for i:=0 to n-1 do f[i,0]:=1;

      for r:=1 to sr do
      for i:=0 to n-1 do
        begin
          for j:=0 to n-1 do
            if (i>>r=j>>r) and (i>>(r-1)<>j>>(r-1)) then
              f[i,r]+=f[j,r-1]*p[i,j];
          f[i,r]*=f[i,r-1];
        end;

      for i:=1 to n do
        ind[i]:=i-1;
    end;

function lower(a,b:longint):boolean;
    begin
      if abs(f[a,sr]-f[b,sr])>1e-30 then
        begin
          exit( f[a,sr]>f[b,sr] );
        end;
      exit(a<b);
    end;

procedure sort(l,r:longint);
    var
      mid,i,j,tmp:longint;
    begin
      i:=l; j:=r; mid:=ind[l+random(r-l+1)];
      repeat
        while lower(ind[i],mid) do inc(i);
        while lower(mid,ind[j]) do dec(j);
        if i<=j then
          begin
            tmp:=ind[i];
            ind[i]:=ind[j];
            ind[j]:=tmp;
            inc(i); dec(j);
          end;
      until i>j;
      if i<r then sort(i,r);
      if l<j then sort(l,j);
    end;

procedure ans;
    var
      i:longint;
    begin
      for i:=1 to n do
        writeln(f2,ind[i]+1);
    end;

begin
  openF;
  inp;
  solve;
  randseed:=7777;
  sort(1,n);
  ans;
  closeF;
end.

Code mẫu của hieult

#include <stdio.h>
//#include <conio.h>

int main()
{
   // freopen("FACUP.in","r",stdin);
    int n,mu2[10],a[257][257],flag[257][257],so[257];
    double kq[257][10];
    scanf("%d",&n);
    mu2[0]=1; for(int i = 1;i<=n;i++) mu2[i] = mu2[i-1]*2;
    for(int i = 1;i<=mu2[n];i++)
    {
        so[i] = i;
        for(int j = 1;j<=mu2[n];j++)
        {
            scanf("%d",&a[i][j]);
            if(i==j) flag[i][j]=1;
            else flag[i][j]=0;
        }
    }
    for(int i = 1;i<=mu2[n];i++)
        kq[i][0]=1;
    for(int ii = 1;ii<=n;ii++)
    {
        for(int i = 1;i<=mu2[n];i++)
        {
            kq[i][ii]=0;
            int k = (i-1)/mu2[ii];
            for(int j = k*mu2[ii]+1;j<=k*mu2[ii]+mu2[ii];j++)
            {

                if(flag[i][j]==0)
                     kq[i][ii]=kq[i][ii]+kq[i][ii-1]*kq[j][ii-1]*a[i][j]/100;
                flag[i][j]=1;
            }
           // printf("%d %d %lf\n",i,ii,kq[i][ii]);
        }
    }
    int check = 0;
    while(check==0)
    {
        check = 1;
        for(int i = 1;i<=mu2[n]-1;i++)
        {
            if(kq[i][n]<kq[i+1][n])
            {
                 double temp = kq[i][n];
                 kq[i][n] = kq[i+1][n];
                 kq[i+1][n] = temp;
                 int temp1 = so[i];
                 so[i] = so[i+1];
                 so[i+1] = temp1;
                 check = 0;
            }
        }
    }
    for(int i = 1;i<=mu2[n];i++)
        printf("%d\n",so[i]);
   // getch();
}

Code mẫu của ll931110

{$N+}
Program FACUP;
Const
  input  = '';
  output = '';
  maxk = 256;
  maxn = 8;
Var
  n,k: integer;
  a: array[1..maxk,1..maxk] of integer;
  duel: array[1..maxk,1..maxk,1..maxn] of boolean;
  ch: array[1..maxk,0..maxn] of real;
  d: array[1..maxk] of real;
  pos: array[1..maxk] of integer;

Procedure init;
Var
  f: text;
  i,j: integer;
Begin
  Assign(f, input);
    Reset(f);

  Readln(f, n);
  k:= 1 shl n;
  For i:= 1 to k do
    For j:= 1 to k do read(f, a[i,j]);

  Close(f);
End;

Procedure gens;
Var
  i,j,x,y,s: integer;
Begin
  For i:= 1 to k do pos[i]:= i;

  Fillchar(duel, sizeof(duel), false);
  For i:= 1 to n do
    Begin
      s:= 1 shl i;
      For j:= 1 to k do
        if j mod s = 1 then
          Begin
            For x:= j to j + s div 2 - 1 do
              For y:= j + s div 2 to j + s - 1 do
                Begin
                  duel[x,y,i]:= true;
                  duel[y,x,i]:= true;
                End;
          End;
    End;
End;

Procedure solve;
Var
  i,j,t: integer;
Begin
  Fillchar(ch, sizeof(ch), 0);
  For i:= 1 to k do ch[i,0]:= 100;

  For i:= 1 to n do
    For j:= 1 to k do
      Begin
        For t:= 1 to k do
          if duel[j,t,i] then ch[j,i]:= ch[j,i] + ch[t,i - 1] * a[j,t] / 100;
        ch[j,i]:= ch[j,i] * ch[j,i - 1] / 100;
      End;

  For i:= 1 to k do d[i]:= ch[i,n];
End;

Procedure BubbleSort;
Var
  i,j,t: integer;
  tmp: real;
Begin
  For i:= 1 to k - 1 do
    For j:= i + 1 to k do
      if (d[i] < d[j]) or (d[i] = d[j]) and ((pos[i] > pos[j])) then
        Begin
          t:= pos[i];
          pos[i]:= pos[j];
          pos[j]:= t;

          tmp:= d[i];
          d[i]:= d[j];
          d[j]:= tmp;
        End;
End;

Procedure printresult;
Var
  f: text;
  i: integer;
Begin
  Assign(f, output);
    Rewrite(f);
    For i:= 1 to k do writeln(f, pos[i]);
  Close(f);
End;

Begin
  init;
  gens;
  solve;
  BubbleSort;
  printresult;
End.

Code mẫu của skyvn97

#include<algorithm>
#include<cstdio>
#define MAX   575
#define FOR(i,a,b) for (int i=(a);i<=(b);i=i+1)
#define REP(i,n) for (int i=0;i<(n);i=i+1)
using namespace std;
double p[MAX][MAX];
double f[MAX][MAX];
int ans[MAX];
const double eps=1e-9;
int n;
bool cmp(const int &i,const int &j) {
    if (f[i][n]>f[j][n]) return (true);
    if (f[j][n]>f[i][n]) return (false);
    return (i<j);
}
void init(void) {
    int t;
    scanf("%d",&n);
    REP(i,1<<n) REP(j,1<<n) {
        scanf("%d",&t);
        p[i][j]=1.0*t/100;
    }
}
void optimize(void) {
    REP(i,1<<n) f[i][0]=1.0;
    FOR(j,1,n) REP(i,1<<n) {
        int num=i/(1<<(j-1));
        if (num%2==0) num++; else num--;
        REP(k,1<<(j-1)) {
            int t=num*(1<<(j-1))+k;
            f[i][j]+=f[i][j-1]*f[t][j-1]*p[i][t];
        }
    }
}
void print(void) {
    REP(i,1<<n) ans[i]=i;
    sort(ans,ans+(1<<n),cmp);
    REP(i,1<<n) printf("%d\n",ans[i]+1);
}
int main(void) {
    init();
    optimize();
    print();
    return 0;
}

Code mẫu của khuc_tuan

#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;

int n, N;
int a[1025][1025];
pair<double, int> ds[1025];

vector<double> calc( int left, int right) {
    vector<double> res;
    if(left==right) {
        res.push_back(1);
        return res;
    }
    int mid = (left+right) / 2;
    vector<double> r1 = calc( left, mid);
    vector<double> r2 = calc( mid+1, right);
    for(int i=left;i<=mid;++i) {
        double t = 0;
        for(int j=mid+1;j<=right;++j)
            t += r2[j-mid-1] * a[i][j] / 100.0;
        res.push_back( t * r1[i-left] );
    }
    for(int i=mid+1;i<=right;++i) {
        double t = 0;
        for(int j=left;j<=mid;++j)
            t += r1[j-left] * a[i][j] / 100.0;
        res.push_back( t * r2[i-mid-1] );
    }
    return res;
}

bool cmp(pair< double, int > p1, pair<double, int> p2) {
    if(p1.first==p2.first) return p1.second < p2.second;
    return p1.first > p2.first;
}

int main() {
    scanf("%d", &n);
    N = 1<<n;
    for(int i=0;i<N;++i) for(int j=0;j<N;++j) scanf("%d", a[i]+j);
    vector<double> res = calc( 0, N-1);
    for(int i=0;i<N;++i) ds[i] = make_pair( res[i], i+1);
    sort( ds, ds + N, cmp);
    for(int i=0;i<N;++i) printf("%d\n", ds[i].second);
    //system("pause");
    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.