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.

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

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.