Editorial for VM 08 Bài 19 - Cúp FA
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.
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 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; }
Comments