1. 程式人生 > >2013-2014 ACM-ICPC Brazil Subregional Programming Contest 題解

2013-2014 ACM-ICPC Brazil Subregional Programming Contest 題解

題目連結

這場比賽題面英文都好長... ...

模擬。

#include <bits/stdc++.h>
using namespace std;

int main() {
  int a,b,c;
  cin>>a>>b>>c;
  if(a != b && a!=c) {
    cout <<"A";
    return 0;
  }
  if(b != a && b!=c) {
    cout <<"B";
    return 0;
  }
  if(a != c && b!=c) {
    cout <<"C";
    return 0;
  }
  cout <<"*";
  return 0;
}

找到每一條線段上面那條是什麼,然後用並查集就可以求出來每個點最終會到哪裡。

尋找每條線段上面那條,可以按照$y$進行排序,然後線段樹區間覆蓋進行操作。

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 10;
int n, Q;
struct X {
  int x1, y1;
  int x2, y2;
}s[maxn];
int nx[maxn];
int f[maxn];
int root[maxn];

int Find(int x) {
  if(x != f[x]) f[x] = Find(f[x]);
  return f[x];
}

bool cmp(const X& a, const X& b) {
  if(a.y2 != b.y2) return a.y2 > b.y2;
  return a.y1 > b.y1;
}

int t[maxn * 40];

void pushDown(int rt) {
  if(t[rt] == 0) return;
  t[2 * rt] = t[rt];
  t[2 * rt + 1] = t[rt];
  t[rt] = 0;
}

void build(int l, int r, int rt) {
  t[rt] = -1;
  if(l == r) return;
  int mid = (l + r) / 2;
  build(l, mid, 2 * rt);
  build(mid + 1, r, 2 * rt + 1);
}

void update(int L, int R, int val, int l, int r, int rt) {
  if(L <= l && r <= R) {
    t[rt] = val;
    return;
  }
  pushDown(rt);
  int mid = (l + r) / 2;
  if(L <= mid) update(L, R, val, l, mid, 2 * rt);
  if(R > mid) update(L, R, val, mid + 1, r, 2 * rt + 1);
}

int get(int pos, int l, int r, int rt) {
  if(l == r) {
    return t[rt];
  }
  pushDown(rt);
  int mid = (l + r) / 2;
  if(pos <= mid) return get(pos, l, mid, 2 * rt);
  else return get(pos, mid + 1, r, 2 * rt + 1);
}

int main() {
  scanf("%d%d", &n, &Q);
  for(int i = 1; i <= n; i ++) {
    f[i] = i;
    root[i] = 0;
    scanf("%d%d", &s[i].x1, &s[i].y1);
    scanf("%d%d", &s[i].x2, &s[i].y2);
    if(s[i].y1 > s[i].y2) {
      swap(s[i].x1, s[i].x2);
      swap(s[i].y1, s[i].y2);
    }
  }
  sort(s + 1, s + 1 + n, cmp);
  
  
  for(int i = 1; i <= n; i ++) {
  //  printf("%d %d %d %d\n", s[i].x1, s[i].y1, s[i].x2, s[i].y2);
  }
  
  
  build(0, 1e6 + 10, 1);
  
  for(int i = 1; i <= n; i ++) {
    if(s[i].y1 == s[i].y2) {
      nx[i] = i;
    } else {
      nx[i] = get(s[i].x2, 0, 1e6 + 10, 1);
    }
    update(min(s[i].x1, s[i].x2), max(s[i].x1, s[i].x2), i, 0, 1e6 + 10, 1);
  }
  
  for(int i = 1; i <= n; i ++) {
    if(nx[i] == -1 || nx[nx[i]] == nx[i]) {
      root[i] = 1;
    }
  }

  for(int i = 1; i <= n; i ++) {
    if(root[i]) continue;
    f[i] = nx[i];
    Find(i);
    nx[i] = f[i];
  }
  
  for(int i = 1; i <= n; i ++) {
 //   printf("%d : %d\n", i, nx[i]);
  }
  
  while(Q --) {
    int x;
    scanf("%d", &x);
    int id = get(x, 0, 1e6 + 10, 1);
    if(id == -1) {
      printf("%d\n", x);
      continue;
    }
    if(nx[id] == id) {
      printf("%d %d\n", x, s[id].y1);
      continue;
    }
    int now = id, pre = -1;
  //  printf("!!! %d\n", now);
    while(1) {
      pre = now;
      now = nx[now];
      if(now == nx[now] || now == -1) break;
    }
    if(now == -1) {
      printf("%d\n", s[pre].x2);
    } else {
      printf("%d %d\n", s[pre].x2, s[now].y2);
    }
  }
  
  return 0;
}

/*
 4 4
 0 1 3 3
 1 5 6 5
 5 3 2 4
 7 4 10 2
 2
 5
 8
 6
 
 4 3
 1 3 4 2
 10 3 7 4
 2 3 8 3
 3 5 5 4
 4
 9
 8
 
 */

模擬,資料範圍很少,平方的效率就可以了。

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1000;
int n, m, q;
vector<int> g[maxn];
int belong[maxn];
int fac[maxn];
int age[maxn];
int ans;
int f[maxn];

void dfs(int x, int y) {
  if(f[x]) return;
 // printf("debug %d\n", fac[x]);
  f[x] = 1;
  if(x != y) ans = min(ans, age[fac[x]]);
  for(int i = 0; i < g[x].size(); i ++) {
    dfs(g[x][i], y);
  }
}

int main() {
  scanf("%d%d%d", &n, &m, &q);
  for(int i = 1; i <= n; i ++) {
    belong[i] = i;
    fac[i] = i;
    scanf("%d", &age[i]);
  }
  while(m --) {
    int u, v;
    scanf("%d%d", &u, &v);
    g[v].push_back(u);
  }
  
  while(q --) {
    char op[10];
    scanf("%s", op);
    if(op[0] == 'T') {
      int x, y;
      scanf("%d%d", &x, &y);
      swap(belong[x], belong[y]);
      for(int i = 1; i <= n; i ++) {
        fac[belong[i]] = i;
      }
    } else {
      int x;
      scanf("%d", &x);
      ans = 200;
      for(int i = 1; i <= n; i ++) {
        f[i] = 0;
      }
      dfs(belong[x], belong[x]);
      if(ans == 200) printf("*\n");
      else printf("%d\n", ans);
    }
  }
  return 0;
}

/*
 7 8 9
 21 33 33 18 42 22 26
 1 2
 1 3
 2 5
 3 5
 3 6
 4 6
 4 7
 6 7
 P 7
 T 4 2
 P 7
 P 5
 T 1 4
 P 7
 T 4 7
 P 2
 P 6
 
 
 6 5 6
 10 20 30 40 50 60
 1 5
 1 4
 3 6
 2 5
 4 5
 P 1
 P 5
 P 6
 T 1 6
 P 1
 P 4
 
 */

爆搜,用序列的hash值進行剪枝。

#include <bits/stdc++.h>
using namespace std;

const long long mod = 1e9 + 7;
const long long base = 131LL;
const int maxn = 20;
int n, m;
int a[maxn], b[maxn];
int ans;
int to[maxn];

map<long long, int> ha;

long long Get(int x) {
  long long res = 0;
  for(int i = 1; i <= x; i ++) {
    res = res * base % mod;
    res = res + to[i];
    res = res % mod;
  }
  return res;
}

void dfs(int x) {

  if(x < m) return;
  
  if(x == m) {
    int fail = 0;
    for(int i = 1; i <= m; i ++) {
      if(a[i] != b[i]) fail = 1;
    }
    if(fail == 0) ans = 1;
   // return;
  }
  
  int tmp[maxn];
  for(int i = 1; i <= x; i ++) {
    tmp[i] = a[i];
  }
  
  for(int i = 0; i < x; i ++) {
    int left = i;
    int right = x - left;
    if(max(left, right) < m) continue;
    int len = max(left, right);
    memset(to, 0, sizeof to);
    if(left > right) {
      for(int i = 1; i <= left; i ++) {
        to[i] = tmp[i];
      }
      int p = n;
      for(int i = left - right + 1; i <= left; i ++) {
        to[i] += tmp[p];
        p --;
      }
    } else {
      int p = x;
      for(int i = 1; i <= right; i ++) {
        to[i] = tmp[p];
        p --;
      }
      p = left;
      for(int i = right; p; i --) {
        to[i] += tmp[p];
        p --;
      }
    }
    
    long long to_ha = Get(len);
    if(ha[to_ha]) continue;
    ha[to_ha] = 1;
    for(int i = 1; i <= len; i ++) {
      a[i] = to[i];
    }
    dfs(len);
    
    if(ans == 1) return;
  }
  
  for(int i = 1; i <= x; i ++) {
    a[i] = tmp[i];
  }
}

int main() {
  int suma=0,sumb=0;
  scanf("%d", &n);
  for(int i = 1; i <= n; i ++) scanf("%d", &a[i]), suma += a[i];
  scanf("%d", &m);
  for(int i = 1; i <= m; i ++) scanf("%d", &b[i]), sumb += b[i];
  
  if(suma == sumb && n >= m)
  dfs(n);
  if(ans) printf("S\n");
  else printf("N\n");
  return 0;
}


/*
 7
 5 6 23 8 19 7 10
 4
 5 16 30 27
 
 7
 1 2 3 4 5 6 7
 5
 7 6 5 5 5
 
 4
 1 2 3 4
 1
 10
 
 6
 19 23 3 51 2 0
 2
 34 64
 
 6
 1 2 3 4 5 6
 6
 1 2 3 4 5 6
 */

模擬。

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 10;
int f[maxn];
vector<int> ans;

int main() {
  int n, r;
  scanf("%d%d", &n, &r);
  for(int i = 1; i <= r; i ++) {
    int x;
    cin >> x;
    f[x] = 1;
  }
  for(int i = 1; i <= n; i ++) {
    if(f[i]) continue;
    ans.push_back(i);
  }
  if(ans.size() == 0) {
    printf("*");
  } else {
    for(int i = 0; i < ans.size(); i ++) {
      printf("%d", ans[i]);
      if(i < ans.size() - 1) printf(" ");
      else printf("\n");
    }
  }
  return 0;
}

列舉起點,然後二分兩個中間點。

#include <bits/stdc++.h>
using namespace std;

const int maxn = 5e5 + 10;
long long a[maxn];
long long sum[maxn];

int main() {
  int n;
  scanf("%d", &n);
  int ans = 0;
  for(int i = 1; i <= n; i ++) {
    scanf("%lld", &a[i]);
    a[i + n] = a[i];
  }
  for(int i = 1; i <= 2 * n; i ++) {
    sum[i] = sum[i - 1] + a[i];
  }
  if(sum[n] % 3) {
    printf("%d\n", 0);
    return 0;
  }

  for(int i = 1; i <= n; i ++) {
    int L, R, p;
    
    L = i, R = i + n - 1, p = -1;
    while(L <= R) {
      int mid = (L + R) / 2;
      long long num = sum[mid] - sum[i - 1];
      if(num == sum[n] / 3) {
        p = mid;
        break;
      } else if(num < sum[n] / 3) {
        L = mid + 1;
      } else {
        R = mid - 1;
      }
    }
    if(p == -1) continue;
    
    int tmp = p;
    L = p + 1, R = i + n - 1, p = -1;
    while(L <= R) {
      int mid = (L + R) / 2;
      long long num = sum[mid] - sum[tmp];
      if(num == sum[n] / 3) {
        p = mid;
        break;
      } else if(num < sum[n] / 3) {
        L = mid + 1;
      } else {
        R = mid - 1;
      }
    }
    if(p == -1) continue;
    //printf("debug : %d\n", i);
    ans ++;
  }
  printf("%d\n", ans / 3);
  return 0;
}


/*
 8
 4 2 4 2 2 6 2 2
 
 6
 3 4 2 1 5 3
 */

可以發現,行列是獨立的。即我們可以抓出每行的最小值,按最小值進行行調整。然後隨便抓一行,按這一行的列上的值進行調整,這一行調整完畢之後檢查其餘行。

#include <bits/stdc++.h>
using namespace std;

int a[500][500];
int mn[500];
int tmp[500];
int n, m;
int ans;

void swapR(int x, int y) {
  for(int j = 1; j <= m; j ++) {
    swap(a[x][j], a[y][j]);
  }
}

void swapC(int x, int y) {
  for(int i = 1; i <= n; i ++) {
    swap(a[i][x], a[i][y]);
  }
}

int main() {
  scanf("%d%d", &n, &m);
  for(int i = 1; i <= n; i ++) {
    mn[i] = 1000000;
    for(int j = 1; j <= m; j ++) {
      scanf("%d", &a[i][j]);
      mn[i] = min(mn[i], a[i][j]);
    }
  }
  
  int fail = 0;
  
  for(int i = 1; i <= n; i ++) {
    tmp[i] = mn[i];
  }
  sort(tmp + 1, tmp + n + 1);
  
  for(int i = 1; i <= n; i ++) {
    if(tmp[i] == mn[i]) continue;
    int pos;
    for(int j = 1; j <= n; j ++) {
      if(mn[j] == tmp[i]) pos = j;
    }
    ans ++;
    swap(mn[i], mn[pos]);
    swapR(i, pos);
  }
  
  for(int j = 1; j <= m; j ++) {
    tmp[j] = mn[j] = a[1][j];
  }
  sort(tmp + 1, tmp + m + 1);
  
  for(int j = 1; j <= m; j ++) {
    if(tmp[j] == mn[j]) continue;
    int pos;
    for(int i = 1; i <= m; i ++) {
      if(mn[i] == tmp[j]) pos = i;
    }
    ans ++;
    swap(mn[j], mn[pos]);
    swapC(j, pos);
  }
  
  

  int num = 1;
  for(int i = 1; i <= n; i ++) {
    for(int j = 1; j <= m; j ++) {
      if(a[i][j] != num) fail = 1;
      num ++;
    }
  }
  
  if(fail) {
    printf("*");
  } else {
    printf("%d\n", ans);
  }
  
  return 0;
}

/*
 
 2 2
 3 4
 1 2
 
 3 3
 9 2 4
 5 8 7
 6 1 3
 
 5 4
 13 15 14 16
 5 7 6 8
 9 11 10 12
 1 3 2 4
 17 19 18 20
 
 */

斐波那契數列變了一下,方案數${f_i} = L \times {f_{i - 2}} + K \times {f_{i - 1}}$矩陣快速冪加速即可

#include <bits/stdc++.h>
using namespace std;

const long long mod = 1e6;

long long n, K, L;

struct Matrix
{
  long long A[4][4];
  int R, C;
  Matrix operator*(Matrix b);
};

Matrix Matrix::operator*(Matrix b)
{
  Matrix c;
  memset(c.A,0,sizeof(c.A));
  int i,j,k;
  for(i=1; i<=R; i++)
    for(j=1; j<=b.C; j++)
      for(k=1; k<=C; k++)
        c.A[i][j]=((A[i][k]*b.A[k][j])%mod+c.A[i][j])%mod;
  c.R=R; c.C=b.C;
  return c;
}

Matrix X, Y, Z;

long long init(long long a, long long b, long long c)
{
  b = b % mod;
  c = c % mod;
  
  memset(X.A,0,sizeof X.A);
  memset(Y.A,0,sizeof Y.A);
  memset(Z.A,0,sizeof Z.A);

  Z.A[1][1] = 1;
  Z.A[1][2] = b;
  Z.R = 1; Z.C = 2;
  
  for(int i=1;i<=2;i++) Y.A[i][i]=1;
  Y.R = 2; Y.C = 2;
  
  X.A[1][1] = 0; X.A[1][2] = c;
  X.A[2][1] = 1; X.A[2][2] = b;
  X.R = 2; X.C = 2;
  
  while (a)
  {
    if (a % 2 == 1) Y = Y*X;
    a = a >> 1;
    X = X*X;
  }
  Z = Z*Y;
  
  return Z.A[1][1];
}

int main() {
  cin >> n >> K >> L;
  n /= 5;
  printf("%06lld\n", init(n, K, L));
  return 0;
}

$dp[i]$表示修補到$i$個洞為止的最小花費。

感覺這題可以加強一下,因為輪子是一個環,再加上一個列舉起點也不算過分吧...

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2000;
int n;
int a[maxn];
int dp[maxn];
int t1, t2;
int C;

int main() {
  scanf("%d%d%d%d", &n, &C, &t1, &t2);
  for(int i = 1; i <= n; i ++) {
    scanf("%d", &a[i]);
  }
  sort(a + 1, a + 1 + n);
  for(int i = 1; i <= n; i ++) {
    dp[i] = dp[i - 1] + min(t1, t2);
    int pos1 = -1, pos2 = -1;
    for(int j = i - 1; j >= 1; j --) {
      if(a[i] - a[j] <= t1) pos1 = j;
      if(a[i] - a[j] <= t2) pos2 = j;
    }
    if(pos1 != -1) {
      dp[i] = min(dp[i], dp[pos1 - 1] + t1);
    }
    if(pos2 != -1) {
      dp[i] = min(dp[i], dp[pos2 - 1] + t2);
    }
  }
  printf("%d\n", dp[n]);
  return 0;
}

/*
 5 20 2 3
 2 5 8 11 15
 
 4 20 12 9
 1 2 3 13
 */

先求出最大生成樹,這個時候把必要的長度最長的邊都保留下來了。

對於每一次的詢問,就是求兩點的路徑上的最小權值,可以倍增處理。

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 10;
int n, m, Q;
struct Edge {
  int u, v, w;
}e[maxn];

int belong[maxn];

int h[maxn], to[maxn], cost[maxn], nx[maxn], cnt;
int f[maxn], dep[maxn], too[maxn][35], mn[maxn][35], idx[maxn][35];

void add(int u, int v, int c) {
  to[cnt] = v;
  nx[cnt] = h[u];
  cost[cnt] = c;
  h[u] = cnt ++;
}

int Find(int x) {
  if(x != belong[x]) return belong[x] = Find(belong[x]);
  return belong[x];
}

bool cmp(const Edge &a, const Edge &b) {
  return a.w > b.w;
}

void dfs(int fa,int x,int y,int eid)
{
  f[x]=fa; dep[x]=y;
  if(x==1)
  {
    too[x][0] = -1;
    mn[x][0] = 1e6;
  }
  else
  {
    too[x][0] = fa;
    mn[x][0] = cost[eid];
  }
  
  for(int j=1;j<=30;j++)
  {
    if((1<<j) > dep[x]-1) {
      too[x][j] = -1;
      mn[x][j] = 1e6;
    } else {
      too[x][j] = too[too[x][j-1]][j-1];
      mn[x][j] = min(mn[x][j-1], mn[too[x][j-1]][j-1]);
    }
  }
  
  for(int i = h[x]; i != -1; i = nx[i])
  {
    int v = to[i];
    if(v == fa) continue;
    if(f[v] != 0) continue;
    dfs(x, v, y + 1, i);
  }
}

int F(int a,int b)
{
  if(dep[a]<dep[b]) swap(a,b);
  
  int MN=1e6;
  if(dep[a]!=dep[b])
  {
    while(1)
    {
      int L=0,R=30,pos;
      while(L<=R)
      {
        int mid=(L+R)/2;
        if(too[a][mid]!=-1&&dep[too[a][mid]]>=dep[b]) L=mid+1,pos=mid;
        else R=mid-1;
      }
      
      if(mn[a][pos]<=MN) MN=mn[a][pos];
      
      a=too[a][pos];
      if(dep[a]==dep[b]) break;
    }
  }
  
  if(a==b) return MN;
  
  while(1)
  {
    if(f[a]==f[b])
    {
      if(mn[a][0]<=MN) MN=mn[a][0];
      if(mn[b][0]<=MN) MN=mn[b][0];
      break;
    }
    
    int L=0,R=30,pos;
    while(L<=R)
    {
      int mid=(L+R)/2;
      if(too[a][mid]!=too[b][mid]) L=mid+1,pos=mid;
      else R=mid-1;
    }
    
    if(mn[a][pos]<=MN) MN=mn[a][pos];
    if(mn[b][pos]<=MN) MN=mn[b][pos];
    
    a=too[a][pos];
    b=too[b][pos];
  }
  
  return MN;
}

int main() {
  scanf("%d%d%d", &n, &m, &Q);
  for(int i = 1; i <= n; i ++) {
    belong[i] = i;
    h[i] = -1;
  }
  for(int i = 1; i <= m; i ++) {
    scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
  }
  sort(e + 1, e + 1 + m, cmp);
  
  for(int i = 1; i <= m; i ++) {
    int fa = Find(e[i].u);
    int fb = Find(e[i].v);
    if(fa == fb) continue;
    belong[fa] = fb;
  //  printf("debug %d %d %d\n", e[i].u, e[i].v, e[i].w);
    add(e[i].u, e[i].v, e[i].w);
    add(e[i].v, e[i].u, e[i].w);
  }

  dfs(-1, 1, 1, -1);
  
  while(Q --) {
    int x, y;
    scanf("%d%d", &x, &y);
    printf("%d\n", F(x, y));
  }
  
  return 0;
}


/*
 4 5 4
 1 2 9
 1 3 0
 2 3 8
 2 4 7
 3 4 4
 1 4
 2 1
 3 1
 4 3
 
 4 5 2
 1 2 30
 2 3 20
 3 4 10
 4 1 40
 2 4 50
 1 3
 1 2
 
 */

相關推薦

2013-2014 ACM-ICPC Brazil Subregional Programming Contest 題解

【題目連結】 這場比賽題面英文都好長... ... 模擬。 #include <bits/stdc++.h> using namespace std; int main() { int a,b,c; cin>>a>>b>>

2018-2019 ACM-ICPC Brazil Subregional Programming Contest

A:留坑 B:二維sg函式,特判邊界情況 //#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pragma GCC optimize(4) //#pragma GCC optimize("unroll-loops") //#pragma commen

2013-2014 ACM-ICPC, NEERC, Moscow Subregional Contest2013區域賽練習)

比賽出了A,B,H,I,   隊友在比賽中惡搞K題TLE,導致F題沒時間除錯,賽後加了一句flag = 0,F題就AC了,一個小細節沒注意。 B題儲存了一份好的程式碼 F題 是一半模擬  一半DP, F題程式碼在下面。 K題惡搞 https://github.com/AC

The 2018 ACM-ICPC Chinese Collegiate Programming Contest Take Your Seat

scanf com 分享圖片 pro name string 技術 證明 double /* 證明過程如下 :第一種情況:按1到n的順序上飛機,1會隨意選一個,剩下的上去時若與自己序號相同的座位空就坐下去,若被占了就也會隨意選一個。求最後一個人坐在應坐位置的概率 *

2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) A. Altruistic Amphibians DP

題目連結:https://codeforc.es/gym/101933/problem/A 題意:有 n 只青蛙在一個坑裡面,要求可以跳出坑的青蛙的最大數量。每個青蛙有 3 種屬性:l 為青蛙一次可以跳的高度,w 為青蛙的重量,h 為青蛙作為墊背時的高度,墊背的前提是墊背的青蛙的重量比在他上面的青蛙的總重量

2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) D. Delivery Delays 二分+最短路+DP

題目連結:https://codeforc.es/gym/101933/problem/D 題意:地圖上有 n 個位置和 m 條邊,每條邊連線 u、v 且有一個距離 w,一共有 k 個詢問,每個詢問表示 ti 時間在位置 ui 有人下單點了披薩,而披薩店在 di 時間做好披薩可以送出去,披薩店在位置 1,送

2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)

傳送門 A.Altruistic Amphibians     一個挺有意思的題目。首先考慮這樣的問題:倘若要讓儘可能多的青蛙能夠逃跑,則顯然羅漢最好疊得儘可能的高(這才能使得那些不能一次性跳出的青蛙能夠逃離)。     而顯然,對於那些體重最

A - Multiplication Dilemma (思維)( 2018 ACM ICPC Arabella Collegiate Programming Contest

滴答滴答---題目連結  Multiplication operation is not always easy! For example, it is hard to calculate 27 × 20 using your mind, but it is eas

The 2014 ACM-ICPC Asia Anshan Regional Contest

A題 - Twelve Months 沒法補   B題 - Chat 大模擬,隊友已補   C題 - Coprime 三角形同色模型。假設有n個元素,每兩個元素間都存在兩種不同的關係A和B。現在要求找出所有三元組,使得它們兩兩間均為關係A或關係B

2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017)(solve7/11)

B題 題意:給你n個人的第一棒的速度和其他棒的速度,然後讓你輸出最快的那個組合,輸出時間和人。 思想:模擬 D題 題意:給你n個01串代表每個人的特徵,現在讓你求一個和他們長度相等但是和他們相似度最對的那個串。 思想:考慮最短路問題,將每個串拆出來k個差一位的子

Multiplication Dilemma (思維)( 2018 ACM ICPC Arabella Collegiate Programming Contest

Multiplication operation is not always easy! For example, it is hard to calculate 27 × 20 using your mind, but it is easier to find the

2018 ACM-ICPC, Syrian Collegiate Programming Contest F - Pretests SOS dp

#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define

2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017) 部分題/平衡樹/最小環/思路bfs

交題地址 難度按照順序遞增 J - Judging Moose 隊友敲的 #include <iostream> #include <cstdio> using namespace std; int main() {

(寒假GYM開黑)2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018)

put def operator money node tin 自己人 n) n-1 layout: post title: 2018-2019 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2018) auth

2015-2016 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2015) Goblin Garden Guards (數論)

題目大意:在第一象限記憶體在著n個黑點,然後同時存在著圓,求出不在圓內的個數 解題思路:本來這道題在資料很小的時候可以暴力去判,但是發現這個資料太大,所以需要進行優化和處理,我們列舉每個圓,找出這個

(寒假開黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest(爽題)

ogr sign n) you end max ext %d col layout: post title: (寒假開黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest(爽題) author: "l

The 2016 ACM-ICPC Asia Dalian Regional Contest---題解

 題意: 思路:題意真是**了,好不容易才猜對了題意。。是要判M條件是否矛盾。。但是一直讀的題意理解的都是不用判,, 知道題意,就簡單了,可以用二分圖染色,可以2-sat,,那我就比較厲害了,,我啥都沒有,一個dfs隨便搞搞,記錄下顏色,就A了,可怕的是猜題意猜了

ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków

dig contest con amp rap lan ica cal regional ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków Problem A: Rubi

Gym - 100548H The Problem to Make You Happy 2014-2015 ACM-ICPC, Asia Xian Regional Contest (BFS+博弈)

memset 條件 empty reg urn 入隊 acm-icpc () ons 題意:Bob和Alice在一張有向無環圖上移動,給定二者的起點,Bob先手.Bob的失敗條件是不能移動或者與Alice相遇.兩個人都采取最優策略,求Bob是否會贏 分析:銀牌題.先確定所有

2014-2015 ACM-ICPC, Asia Xian Regional Contest(部分題解

摘要   本文主要給出了2014-2015 ACM-ICPC, Asia Xian Regional Contest的部分題解,說明了每題的題意、解題思路和程式碼實現,意即熟悉區域賽比賽題型。   Built with Qinghuai and Ari Factor 題意 判斷是否是