Thursday, January 19, 2017

UVa 1590 - IP Networks

Accepted date: 2017-01-19
Run Time: 0.000
Ranking (as of 2017-01-19): 90 out of 362
Language: C++

Network_address = IP_address & Network_mask.
And for all IP addresses, Network address should be the same.


/*
  UVa 1590 - IP Networks

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_1590_IP_Networks.cpp
*/

#include <cstdio>

const int m_max = 1000;
unsigned int ip_addresses[m_max];

void print_address(unsigned int address)
{
  printf("%u.%u.%u.%u\n", (address & 0xff000000) >> 24, (address & 0x00ff0000) >> 16,
    (address & 0x0000ff00) >> 8, address & 0x000000ff);
}

int main()
{
  const int nr_bits = 32;
  int m;
  while (scanf("%d", &m) != EOF) {
    for (int i = 0; i < m;i++) {
      int b0, b1, b2, b3;
      scanf("%d.%d.%d.%d", &b0, &b1, &b2, &b3);
      ip_addresses[i] = b0 << 24 | b1 << 16 | b2 << 8 | b3;
    }
    unsigned int mask = 0xffffffff, b = 1, address;
    for (int i = 0; i <= nr_bits; i++, mask &= ~b, b <<= 1) {
      address = ip_addresses[0] & mask;
      int j;
      for (j = 1; j < m; j++)
        if ((ip_addresses[j] & mask) != address)
          break;
      if (j == m)
        break;
    }
    print_address(address);
    print_address(mask);
  }
  return 0;
}

Tuesday, January 17, 2017

UVa 12321 - Gas Stations

Accepted date: 2017-01-17
Run Time: 0.030
Ranking (as of 2017-01-17): 79 out of 357
Language: C++

/*
  UVa 12321 - Gas Stations

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_12321_Gas_Stations.cpp
*/

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

const int G_max = 10000;

struct coverage {
  int l_, h_; // coverage is from l_ to h_

bool operator<(const coverage& c) const {return (l_ != c.l_) ? l_ < c.l_ : h_ < c.h_;}
} coverages[G_max];

int main()
{
  while (true) {
    int L, G;
    scanf("%d %d", &L, &G);
    if (!L)
      break;
    for (int i = 0; i < G; i++) {
      int xi, ri;
      scanf("%d %d", &xi, &ri);
      coverages[i].l_ = max(xi - ri, 0), coverages[i].h_ = min(xi + ri, L);
    }
    sort(coverages, coverages + G); // sort the stations by thier lower ends
#ifdef DEBUG
    for (int i = 0; i < G; i++)
      printf("[%d %d]%c", coverages[i].l_, coverages[i].h_, ((i < G - 1) ? ' ' : '\n'));
#endif
    int i = 0, h = 0, l = 0, nr = 0;
    for ( ; l < L && i < G; i++) {
      // discard the stations whose lower end is covered by other station
      const coverage& c = coverages[i];
      if (c.l_ > l) {
        if (c.l_ <= h) {
          l = h, h = 0, nr++;
          if (l == L)
            break;
        }
        else
          break;
      }
      h = max(h, c.h_);
    }
    if (h)
      l = h, nr++;
    printf("%d\n", (l == L) ? G - nr : -1);
  }
  return 0;
}

Saturday, January 14, 2017

UVa 11926 - Multitasking

Accepted date: 2014-07-29
First verdict date: 2014-07-29
Last verdict date: 2016-12-20
Run Time: 0.000
Ranking (as of 2017-01-14): 239 out of 1233
Language: C++

/*
  UVa 11926 - Multitasking

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_11926_Multitasking.cpp
*/

#include <cstdio>
#include <cstring>

const int minutes_max = 1000000;

bool minutes[minutes_max + 1];

int main()
{
  while (true) {
    int n, m;
    scanf("%d %d", &n, &m);
    if (!n && !m)
      break;
    memset(minutes, 0, sizeof(minutes));
    bool conflict = false;
    while (n--) {
      int st, et;
      scanf("%d %d", &st, &et);
      if (conflict)
        continue;
      for (int i = st; i < et; i++) {
        if (minutes[i]) {
          conflict = true; break;
        }
        else
          minutes[i] = true;
      }
    }
    while (m--) {
      int st, et, ri;
      scanf("%d %d %d", &st, &et, &ri);
      if (conflict)
        continue;
      for (int i = 0; i <= minutes_max; i += ri) {
        for (int j = i + st; j <= minutes_max && j < i + et; j++) {
          if (minutes[j]) {
            conflict = true; break;
          }
          else
            minutes[j] = true;
        }
        if (conflict)
          break;
      }
    }
    puts(((conflict) ? "CONFLICT" : "NO CONFLICT"));
  }
  return 0;
}

UVa 465 - Overflow

Accepted date: 2011-07-23
First verdict date: 2011-07-23
Last verdict date: 2017-01-08
Run Time: 0.000
Ranking (as of 2017-01-14): 1144 out of 3584
Language: C++

/*
  UVa 465 - Overflow

  To build using Visucal Studio 2008:
    cl -EHsc -O2 overflow.cpp
*/

#include <iostream>
#include <string>
#include <sstream>
#include <limits>
using namespace std;

int main()
{
  string line;
  while (getline(cin, line)) {
    istringstream iss(line);
    double i, j;
    char op;
    iss >> i >> op >> j;
    double result = (op == '+') ?  i + j : i * j;
    cout << line << endl;
    if (i > numeric_limits<int>::max())
      cout << "first number too big\n";
    if (j > numeric_limits<int>::max())
      cout << "second number too big\n";
    if (result > numeric_limits<int>::max())
      cout << "result too big\n";
  }
  return 0;
}

Thursday, January 12, 2017

UVa 12034 - Race

Accepted date: 2017-01-12
Run Time: 0.000
Ranking (as of 2016-01-12): 54 out of 401
Language: C++

An easy dynamic programming problem.


/*
  UVa 12034 - Race

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_12034_Race.cpp
*/

#include <cstdio>

const int n_max = 1000, modulo = 10056;
int combinations[n_max + 1][n_max + 1];
int nr_ways[n_max + 1]; // nr_ways[i] is the number of way the race can finish with i horses

int main()
{
  // calculate the combinations
  for (int i = 0; i <= n_max; i++)
    combinations[i][0] = 1;
  for (int i = 0; i <= n_max; i++)
    combinations[i][i] = 1;
  for (int i = 1; i <= n_max; i++)
    for (int j = 1; j < i; j++)
      combinations[i][j] = (combinations[i - 1][j - 1] + combinations[i - 1][j]) % modulo;
  nr_ways[1] = 1;
  for (int i = 2; i <= n_max; i++) {
    int nr = 1;
    for (int j = 1; j < i; j++) {
      nr += combinations[i][j] * nr_ways[i - j] % modulo;
      nr %= modulo;
    }
    nr_ways[i] = nr;
  }
  int T;
  scanf("%d", &T);
  for (int t = 1; t <= T; t++) {
    int n;
    scanf("%d", &n);
    printf("Case %d: %d\n", t, nr_ways[n]);
  }
  return 0;
}

Wednesday, January 11, 2017

UVa 12238 - Ants Colony

Accepted date: 2017-01-11
Run Time: 0.330
Ranking (as of 2016-01-11): 31 out of 359
Language: C++

For explanation, see Range Minimum Query and Lowest Common Ancestor - topcoder.


/*
  UVa 12238 - Ants Colony

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_12238_Ants_Colony.cpp
*/

#include <algorithm>
#include <vector>
#include <cstdio>
#ifdef __ELAPSED_TIME__
#include <ctime>
#endif
using namespace std;

const int N_max = 100000;

struct edge {
  int v_;
  int weight_;
  edge(int v, int weight) : v_(v), weight_(weight) {}
};

vector<edge> edges[N_max];

const int level_max = 17; // ceil(log2(N_max))
int levels[N_max]; // level (depth) of node i in the tree
long long weights[N_max]; // weights[i] is the total length from the root to i-th node
int parents[N_max]; // parent node of i
int ancestors[N_max][level_max + 1];
  // ancestors[i][j] is the 2^j-th ancestor of node i

void dfs(int u, int parent, int level)
{
  levels[u] = level;
  const vector<edge>& mes = edges[u];
  for (size_t i = 0; i < mes.size(); i++) {
    int v = mes[i].v_, w = mes[i].weight_;
    if (v != parent) {
      parents[v] = u, weights[v] = w + weights[u];
      dfs(v, u, level + 1);
    }
  }
}

void process3(int n)
{
  for (int i = 0 ; i < n; i++) {
    // the first ancestor of every node i is parents[i]
    ancestors[i][0] = parents[i];
    for (int j = 1; 1 << j < n; j++)
      ancestors[i][j] = -1;
  }
  for (int j = 1; 1 << j < n; j++)
    for (int i = 0; i < n; i++)
      if (ancestors[i][j - 1] != -1)
        ancestors[i][j] = ancestors[ancestors[i][j - 1]][j - 1];
}

long long query(int p, int q)
{
  long long w = weights[p] + weights[q];
  //if p is situated on a higher level than q then we swap them
  if (levels[p] < levels[q])
    swap(p, q);
  // we compute the value of [log2(level[p)]
  int log;
  for (log = 1; 1 << log <= levels[p]; log++)
    ;
  log--;
  // we find the ancestor of node p situated on the same level
  // with q using the values in ancestors[][]
  for (int i = log; i >= 0; i--)
    if (levels[p] - (1 << i) >= levels[q])
      p = ancestors[p][i];
  if (p == q)
  return w - weights[p] * 2;
  // we compute LCA(p, q) using the values in ancestors[][]
  for (int i = log; i >= 0;i--)
    if (ancestors[p][i] != -1 && ancestors[p][i] != ancestors[q][i])
      p = ancestors[p][i], q = ancestors[q][i];
  return w - weights[parents[p]] * 2;
}

int main()
{
#ifdef __ELAPSED_TIME__
  clock_t start = clock();
#endif
  while (true) {
    int N;
    scanf("%d", &N);
    if (!N)
      break;
    for (int i = 0; i < N; i++)
      edges[i].clear();
    for (int v = 1; v < N; v++) {
      int u, w;
      scanf("%d %d", &u, &w);
      edges[u].push_back(edge(v, w)), edges[v].push_back(edge(u, w));
    }
    dfs(0, -1, 0);
    process3(N);
    int Q;
    scanf("%d", &Q);
    while (Q--) {
      int s, t;
      scanf("%d %d", &s, &t);
      printf("%lld%c", query(s, t), ((Q) ? ' ' : '\n'));
    }
  }
#ifdef __ELAPSED_TIME__
  fprintf(stderr, "elapsed time = %lf sec.\n",
    static_cast<double>(clock() - start) / CLOCKS_PER_SEC);
#endif
  return 0;
}

Monday, January 9, 2017

UVa 11732 - "strcmp()" Anyone?

Accepted date: 2017-01-09
Run Time: 0.110
Ranking (as of 2016-01-09): 2 out of 369
Language: C++

You can easily see that the below program works for some input cases of small N.


/*
  UVa 11732 - "strcmp()" Anyone?

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_11732_strcmp_Anyone.cpp
*/

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;

const int N_max = 4000, nr_chars_max = 1000;

struct string {
  char s_[nr_chars_max + 1];

  bool operator<(const string& s) const {return strcmp(s_, s.s_) < 0;}
} strings[N_max];

int nr_comparisons[N_max];
  // nr_comparisons[i] is the number of comparisons between strings[i] and strings[i + 1]

int main()
{
  for (int c = 1; ; c++) {
    int N;
    scanf("%d", &N);
    if (!N)
      break;
    for (int i = 0; i < N; i++)
      scanf("%s", strings[i].s_);
    sort(strings, strings + N);
    for (int i = 0; i < N - 1; i++) {
      const char *cs = strings[i].s_, *ns = strings[i + 1].s_;
      int nr = 1;
      for ( ; *cs == *ns; nr++, cs++, ns++) {
        nr++;
        if (!*cs)
          break;
      }
      nr_comparisons[i] = nr;
    }
    long long T = 0;
    for (int i = 0; i < N - 1; i++) {
      int nr = nr_comparisons[i];
      T += nr;
      for (int j = i + 1; j < N - 1; j++) {
        if (nr_comparisons[j] < nr)
          nr = nr_comparisons[j];
        T += nr;
      }
    }
    printf("Case %d: %lld\n", c, T);
  }
  return 0;
}

Tuesday, January 3, 2017

UVa 10823 - Of Circles and Squares

Accepted date: 2017-01-03
Run Time: 0.000
Ranking (as of 2016-01-03): 8 out of 369
Language: C++

In object oriented programming, the vector of object instances would be created and the in method of each object instance would be called with the query point in question.
The below round function is from UVa OJ Board.


/*
  UVa 10823 - Of Circles and Squares

  To build using Visual Studio 2012:
    cl -EHsc -O2 UVa_10823_Of_Circles_and_Squares.cpp
*/

#include <cstdio>

const int R_max = 100;

struct object {
  int x_, y_; // center or lower left corner
  int length_; // radius or side length
  int r_, g_, b_;
  virtual int in(int px, int py) const = 0;
    // return porasitive value if (px, py) is inside the object, 
    // 0 if (px, py) is on the boundary of the object
    // negative value if (px, py) is outside of the object
};

struct circle : public object {
  virtual int in(int px, int py) const;
} circles[R_max];

struct square : public object {
  virtual int in(int px, int py) const;
} squares[R_max];

int circle::in(int px, int py) const
{
  return length_ * length_ - (px - x_) * (px - x_) - (py - y_) * (py - y_);
}

int square::in(int px, int py) const
{
  if (px == x_ || px == x_ + length_)
    return (py >= y_ && py <= y_ + length_) ? 0 : -1;
  else if (py == y_ || py == y_ + length_)
    return (px >= x_ && px <= x_ + length_) ? 0 : -1;
  else
    return (px > x_ && px < x_ + length_ && py > y_ && py < y_ + length_) ? 1 : -1;
}

int round(int p, int q)   /* Rounds fraction p/q */
{
  return (p / q) + (((2 * (p % q)) >= q) ? 1 : 0);
}

int main()
{
  int T;
  scanf("%d", &T);
  for (int t = 1; t <= T; t++) {
    int R, P;
    scanf("%d %d", &R, &P);
    int nr_circles = 0, nr_squares = 0;
    while (R--) {
      char type[8];
      scanf("%s", type);
      if (type[0] == 'C') { // "CIRCLE"
        circle& c = circles[nr_circles++];
        scanf("%d %d %d %d %d %d", &c.x_, &c.y_, &c.length_, &c.r_, &c.g_, &c.b_);
      }
      else { // "SQUARE"
        square& s = squares[nr_squares++];
        scanf("%d %d %d %d %d %d", &s.x_, &s.y_, &s.length_, &s.r_, &s.g_, &s.b_);
      }
    }
    printf("Case %d:\n", t);
    while (P--) {
      int px, py;
      scanf("%d %d", &px, &py);
      int nr_objects = 0, r = 0, g = 0, b = 0;
      for (int i = 0; i < nr_circles; i++) {
        const circle& c = circles[i];
        int result = c.in(px, py);
        if (!result) {
          nr_objects = 1;
          r = g = b = 0;
#ifdef DEBUG
          printf("on the boundary of circle: %d %d %d\n", c.x_, c.y_, c.length_);
#endif
          break;
        }
        else if (result > 0) {
          nr_objects++;
          r += c.r_, g += c.g_, b += c.b_;
#ifdef DEBUG
          printf("in the circle: %d %d %d\n", c.x_, c.y_, c.length_);
#endif
        }
      }
      if (nr_objects == 1 && !r && !g && !b) // point is on the boundary of an object
        ;
      else {
        for (int i = 0; i < nr_squares; i++) {
          const square& s = squares[i];
          int result = s.in(px, py);
          if (!result) {
            nr_objects = 1;
            r = g = b = 0;
#ifdef DEBUG
          printf("on the boundary of square: %d %d %d\n", s.x_, s.y_, s.length_);
#endif
            break;
          }
          else if (result > 0) {
            nr_objects++;
            r += s.r_, g += s.g_, b += s.b_;
#ifdef DEBUG
          printf("in the square: %d %d %d\n", s.x_, s.y_, s.length_);
#endif
          }
        }
      }
      if (nr_objects)
        printf("(%d, %d, %d)\n",
          round(r, nr_objects), round(g, nr_objects), round(b, nr_objects));
/*
        printf("(%.0lf, %.0lf, %.0lf)\n", static_cast<double>(r) / nr_objects,
          static_cast<double>(g) / nr_objects, static_cast<double>(b) / nr_objects);
*/
      else
        puts("(255, 255, 255)");
    }
    if (t < T)
      putchar('\n');
  }
  return 0;
}