Hướng dẫn giải của Lịch thi đấu bóng đá
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.
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
var n:longint; a,d:array[1..30,1..30] of byte; cur,next,pts,nextt,re:array[1..30] of longint; b:array[0..30,0..1] of longint; procedure rf; var i,j:longint; begin readln(n); fillchar(cur,sizeof(cur),0); fillchar(next,sizeof(next),0); for i:=1 to n do begin for j:=1 to n do begin read(a[i,j]); if a[i,j]=1 then inc(cur[i]); if a[i,j]=2 then inc(next[i]); end; readln; end; end; procedure pr; var i,j,maxcur,k,dem,max,min,maxt,mint:longint; kt:boolean; begin fillchar(re,sizeof(re),0); maxcur:=0; for i:=1 to n do if cur[i]>maxcur then maxcur:=cur[i]; for i:=1 to n do begin fillchar(d,sizeof(d),0); pts:=cur; nextt:=next; pts[i]:=pts[i]+next[i]; nextt[i]:=0; for j:=1 to n do if a[i,j]=2 then begin d[i,j]:=1; d[j,i]:=1; dec(nextt[j]); end; if pts[i]<maxcur then re[i]:=0 else begin if pts[i]=n-1 then begin re[i]:=1; continue; end; repeat kt:=false; for j:=1 to n do if (pts[j]+nextt[j]<=pts[i]) and (nextt[j]>0) then begin pts[j]:=pts[j]+nextt[j]; nextt[j]:=0; kt:=true; for k:=1 to n do if (a[j,k]=2) and (d[j,k]=0) then begin d[j,k]:=1; d[k,j]:=1; dec(nextt[k]); end; end; until not kt; repeat maxt:=0; max:=-1; for j:=1 to n do if nextt[j]>0 then begin if pts[j]>max then begin max:=pts[j]; maxt:=j; end; if pts[j]=max then begin if nextt[j]>nextt[maxt] then maxt:=j; end; end; if maxt=0 then break; min:=n; for j:=1 to n do if (a[maxt,j]=2) and (d[maxt,j]=0) then begin if pts[j]<min then begin min:=pts[j]; mint:=j; end; if pts[j]=min then begin if nextt[j]<nextt[mint] then mint:=j; end; end; inc(pts[mint]); if pts[mint]>pts[i] then break; d[mint,maxt]:=1; d[maxt,mint]:=1; dec(nextt[maxt]); dec(nextt[mint]); until maxt=0; kt:=true; for j:=1 to n do if pts[j]>pts[i] then begin kt:=false; break; end; if kt then re[i]:=1 else re[i]:=0; end; end; end; procedure wf; var i:longint; begin for i:=1 to n do write(re[i]); end; begin rf; pr; wf; 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 = 50; const int M = 1000; using namespace std; int res[N][N]; int c[M][M], f[M][M], T[M]; VI a[M]; int n, nn, s, t, totalFlow; bool bfs() { queue<int> Q; Q.push(s); REP(i, 1, nn) T[i] = 0; while (!Q.empty()) { int u = Q.front(); Q.pop(); TR(v, a[u]) if (T[*v] == 0 && c[u][*v] > f[u][*v]) { T[*v] = u; if (*v == t) return 1; Q.push(*v); } } return 0; } void incFlow() { int delta = INT_MAX; for(int v = t; v != s; v = T[v]) delta = min(delta, c[T[v]][v] - f[T[v]][v]); for(int v = t; v != s; v = T[v]) f[T[v]][v] += delta, f[v][T[v]] -= delta; totalFlow += delta; } bool canBeChampion(int team) { int points[N]; RESET(points, 0); REP(i, 1, n) REP(j, 1, n) if (res[i][j] == 1) points[i] += 3; REP(i, 1, n) if (res[team][i] == 2) points[team] += 3; if (*max_element(points + 1, points + 1 + n) > points[team]) return 0; s = 1; nn = t = 2; REP(i, 1, n) { c[++nn][t] = (points[team] - points[i]) / 3; a[nn].PB(t); } int need = 0; REP(i, 1, n) REP(j, i + 1, n) if (i != team && j != team && res[i][j] == 2) { ++nn; ++need; c[s][nn] = c[nn][i + 2] = c[nn][j + 2] = 1; a[s].PB(nn); a[nn].PB(s); a[nn].PB(i + 2); a[i + 2].PB(nn); a[nn].PB(j + 2); a[j + 2].PB(nn); } totalFlow = 0; while (bfs()) incFlow(); REP(i, 1, nn) a[i].clear(); REP(i, 1, nn) REP(j, 1, nn) c[i][j] = f[i][j] = 0; return totalFlow == need; } int main() { ios :: sync_with_stdio(0); cin.tie(0); cin >> n; REP(i, 1, n) REP(j, 1, n) cin >> res[i][j]; REP(i, 1, n) cout << canBeChampion(i); return 0; }
Code mẫu của RR
//Written by Nguyen Thanh Trung {$R+,Q+} {$Mode objFPC} uses math; const FINP=''; FOUT=''; MAXN=50; oo=1000000; var f1,f2:text; count,n:longint; fl,c,now:array[0..MAXN,0..MAXN] of longint; acc,best,trace,queue:array[0..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 i,j:longint; begin read(f1,n); for i:=1 to n do for j:=1 to n do read(f1,now[i,j]); for i:=1 to n do for j:=1 to n do acc[i]+=now[i,j] and 1; best:=acc; for i:=1 to n do for j:=1 to n do best[i]+=now[i,j]>>1; for i:=1 to n do count+=best[i]-acc[i]; count:=count>>1; end; function findPath:boolean; var first,last,u,v:longint; begin for u:=1 to n+1 do trace[u]:=-1; first:=1; last:=1; queue[1]:=0; while first<=last do begin u:=queue[first]; inc(first); for v:=1 to n+1 do if (trace[v]=-1) and (fl[u,v]<c[u,v]) then begin trace[v]:=u; if v=n+1 then exit(true); inc(last); queue[last]:=v; end; end; exit(false); end; procedure incFlow; var v,u:longint; begin v:=n+1; repeat u:=trace[v]; fl[u,v]+=1; fl[v,u]-=1; v:=u; until v=0; end; function check(u:longint):boolean; var i,j,sum:longint; begin for i:=1 to n do if acc[i]>best[u] then exit(false); fillchar(c,sizeof(c),0); fillchar(fl,sizeof(fl),0); //Xay dung do thi //Kha nang thong qua 0 -> i the hien so van i chua dau //Kha nang thong qua i -> j the hien doi i co the thang j for i:=1 to n do if i<>u then for j:=i+1 to n do if j<>u then begin c[i,j]:=now[i,j]>>1; if now[i,j]=2 then c[0,i]+=1; end; //Kha nang thong qua i -> n+1 the hien so van doi i co the thang //ma van hoa hoac thua u for i:=1 to n do if i<>u then c[i,n+1]:=best[u]-acc[i]; //Tim luong while findPath do incFlow; sum:=0; for i:=1 to n do sum+=fl[0,i]; if sum>=count-(best[u]-acc[u]) then exit(true) else exit(false); end; procedure solve; var i:longint; begin for i:=1 to n do if check(i) then write(f2,1) else write(f2,0); end; begin openF; inp; solve; closeF; end.
Code mẫu của hieult
#include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> #include<cassert> #include<ctime> //nclude<algorithm> #include<iterator> #include<iostream> #include<cctype> #include<string> #include<vector> #include<map> #include<set> #include<queue> #include<list> //nclude<conio.h> #define ep 0.000000001 #define maxn 311 #define oo 1111111111 #define base 100000000 #define TR(c, it) for(typeof((c).begin()) it=(c).begin(); it!=(c).end(); it++) double const PI=4*atan(1); using namespace std; typedef pair<int, int> II; typedef vector<int> VI; typedef vector<II> VII; typedef vector<VI> VVI; typedef vector<VII> VVII; struct dinh{ int diem,chuadau,thutu; }; int n,c[maxn][maxn],f[maxn][maxn]; dinh stack[maxn]; bool kt; //VVI::iterator it; void tao(){ dinh tmp; for(int i = 1;i<=n;i++) stack[i].thutu = i; for(int i = 1;i<=n;i++) for(int j = 1;j<=n;j++){ if(f[i][j]==1) stack[i].diem+=3; else if(f[i][j]==2) stack[i].chuadau = 1; } for(int i = n;i>=2;i--) for(int j = 1;j<=i-1;j++){ if(stack[j].diem > stack[j+1].diem){ tmp = stack[j]; stack[j] = stack[j+1]; stack[j+1] = tmp; } else if(stack[j].diem == stack[j+1].diem && stack[j].chuadau>stack[j+1].chuadau){ tmp = stack[j]; stack[j] = stack[j+1]; stack[j+1] = tmp; } } } void Try(int i,int max){ int tmp; if(!kt) return; tmp = 0; for(int j = 1;j<=n;j++) if(f[i][j]==1) tmp += 3; if(tmp>max){ kt = false; return; } tao(); for(int j = n;j>=1;j--) if(f[i][stack[j].thutu]==2){ if(tmp+3<=max){ tmp = tmp+3; f[i][stack[j].thutu] = 1; f[stack[j].thutu][i] = 0; } else{ f[i][stack[j].thutu] = 0; f[stack[j].thutu][i] = 1; } } if(i!=n) Try(i+1,max); } void xuly(){ int max,k; //oolean kt; for(int i = 1;i<=n;i++){ max = 0; for(int j = 1;j<=n;j++) for(int t = 1;t<=n;t++) f[j][t] = c[j][t]; kt = true; for(int j = 1;j<=n;j++) if(c[i][j] ==1 || c[i][j] ==2){ f[i][j] = 1; f[j][i] = 0; max+=3; } Try(1,max); if(kt) printf("1"); else printf("0"); } } int main(){ //reopen("BONGDA.in","r",stdin); scanf("%d",&n); for(int i = 1;i<=n;i++) for(int j = 1;j<=n;j++){ scanf("%d",&c[i][j]); } if(n==1){ printf("0"); // getch(); return 0; } else xuly(); //etch(); }
Code mẫu của ll931110
#include <algorithm> #include <bitset> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <cstring> #include <deque> #include <fstream> #include <iostream> #include <map> #include <queue> #include <set> #include <stack> #include <string> #include <utility> #include <vector> typedef long long ll; using namespace std; int a[32][32],b[32][32]; int start,end,last_node,num_of_match; int c[502][502],f[502][502]; int trace[502],win[502]; int n; vector<int> adj[502]; bool fin[32]; bool findpath() { memset(trace,-1,sizeof(trace)); trace[start] = -2; queue<int> q; q.push(start); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < adj[u].size(); i++) { int v = adj[u][i]; if (trace[v] == -1 && c[u][v] > f[u][v]) { trace[v] = u; if (v == end) return true; else q.push(v); }; }; }; return false; }; void incflow() { int v = end; while (v != start) { int u = trace[v]; f[u][v]++; f[v][u]--; v = u; }; }; bool winner(int x) { for (int i = 1; i <= n; i++) if (win[i] > win[x]) return false; else c[start][i] = win[x] - win[i]; memset(f,0,sizeof(f)); int time = 0; while (1) { if (!findpath()) break; time++; incflow(); }; return (time >= num_of_match); }; void add_edge(int u,int v,int f1,int f2) { adj[u].push_back(v); adj[v].push_back(u); c[u][v] = f1; c[v][u] = f2; }; int main() { // freopen("bong.in","r",stdin); // freopen("bong.ou","w",stdout); scanf("%d", &n); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) scanf("%d", &a[i][j]); memset(win,0,sizeof(win)); memset(c,0,sizeof(c)); start = 0; for (int i = 1; i <= n; i++) add_edge(start,i,0,0); last_node = n; //Construct network flow for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (a[i][j] == 1) win[i]++; else if (a[i][j] == 2) { if (i > j) continue; last_node++; b[i][j] = last_node; b[j][i] = last_node; add_edge(i,last_node,1,0); add_edge(j,last_node,1,0); }; num_of_match = last_node - n; end = last_node + 1; for (int i = n + 1; i <= last_node; i++) add_edge(i,end,1,0); for (int x = 1; x <= n; x++) { for (int i = 1; i <= n; i++) if (a[x][i] == 2) { int rep = b[x][i]; win[x]++; num_of_match--; c[rep][end] = 0; // This match has ended }; fin[x] = winner(x); //Check the winner for (int i = 1; i <= n; i++) if (a[x][i] == 2) { int rep = b[x][i]; win[x]--; num_of_match++; c[rep][end] = 1; // Rematch }; }; for (int i = 1; i <= n; i++) if (fin[i]) printf("1"); else printf("0"); };
Bình luận